[英]How do I use wait() and notify() if I have one Runnable and one that implements Threads?
[英]how to make runnable instance to wait in one thread and notify by some othrer threads?
在下面的代码中,一个可运行实例正在等待获取通知。 如果我使用方法或一个包含要通知的线程的其他类,如何通过其他线程通知此线程。我被困在这里,请帮助...
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Observable;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.cgi.sample.jms.requestor.RequestorApplication.Runner;
public class RequestorApplication {
public static String correlationId;
static ArrayList<Runner> list = new ArrayList<Runner>();
static Map<Long, Runner> map = new HashMap<Long, Runner>();
static Runner runner;
public static void main(String args[]) throws Exception {
RequestorApplication application = new RequestorApplication();
application.waiter(map);
System.out.println("All the threads are started");
}
public void waiter(Map<Long, Runner> map) {
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 2; i++) {
Runner instance = new Runner();
System.out.println("Executing thread " + " with " + Thread.currentThread().getName());
long threadId = Thread.currentThread().getId();
String threadname = Thread.currentThread().getName();
executor.execute(instance);
RequestorApplication.runner = instance;
synchronized (RequestorApplication.runner) {
map.put(threadId, RequestorApplication.runner);
try {
RequestorApplication.runner.wait();
// notifier(map);
System.out.println(threadname + " Thread entered into waiting state!!!");
// Thread.currentThread().wait();
System.out.println(threadname + " Thread woke up from wait!!!!!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void notifier(Map<Long, Runner> map) {
synchronized (RequestorApplication.runner) {
for (Map.Entry<Long, Runner> entry : map.entrySet()) {
System.out.println("stored threads in map are--->" + map.get(entry.getKey()));
entry.getValue().notify();
}
}
}
class Runner implements Runnable {
public void run() {
System.out.println("runner invoked");
}
}
}
我应该使用包含线程通知的方法还是一个以上的类?
不要notify()
线程。 通知对象 。 Java Concurrency教程的“ Guarded Blocks”部分说明如何使用wait()
和notify()
。 https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
通常,您应该完全避免使用wait()
和notify()
。 它们是低级原语,旨在用于实现高级同步对象。 java.util.concurent
软件包已经具有许多可以使用的更高级别的对象。 这意味着您可以减少编写正确代码的工作,也可以减少需要了解您的代码的其他人的工作。
在下面的代码中,一个可运行实例正在等待获取通知...
您正在使用ExecutorService
线程池,但完全缺少它的重要功能之一。 将作业添加到线程池时,请使用submit(...)
方法,该方法返回Future
对象。 然后,您可以调用future.get()
以等待作业完成并返回值。 您永远不需要自己等待,等等。
Future<Void> future = executor.submit(instance);
// now we wait for the thread to complete
future.get();
另外,尽管它可以工作,但是直接调用Thread.wait()
被认为是非常糟糕的形式。 碰巧在线程完成时会调用notify()
,但这是应该依靠的实现细节。 使用Thread
加入或使用上面的Future.get()
。 另外,如果线程在调用wait()
之前返回,则可能会错过notify()
并且代码将永远不会返回。
最后,正如@ vijayraj34指出的那样,您的代码现在是单线程的,因为您提交了每个作业,然后立即等待它。 您应该做的是派生所有线程并将Future
对象保存在集合中。 然后,一旦开始工作,您就可以依次等待每个Future
。
就像是:
List<Future<Void>> futures = new ArrayList<>();
for (int i = 0; i < 2; i++) {
Runner instance = new Runner();
// save the futures for later
futures.add(executor.submit(instance));
}
// after we submit all of our jobs we shutdown the thread-pool
executor.shutdown();
...
// now we go back and wait for all of the runners that have been working in the background
for (Future<Void> future : futures) {
future.get();
}
@Gray是正确的,但是最好使用completionService而不是直接检索期货,这样可以最大程度地减少等待时间。 当将来的对象可用时,CompletionService允许您从将来获得价值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.