简体   繁体   English

如何使可运行实例在一个线程中等待并由其他线程通知?

[英]how to make runnable instance to wait in one thread and notify by some othrer threads?

in the below code, one runnable instance is waiting to get notify. 在下面的代码中,一个可运行实例正在等待获取通知。 how to notify this thread by some other thread should i use method or one more class which contains thread to notify.. i am stuck here please help... 如果我使用方法或一个包含要通知的线程的其他类,如何通过其他线程通知此线程。我被困在这里,请帮助...

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");

        }

    }

}

Should i use method or one more class which contains thread to notify? 我应该使用包含线程通知的方法还是一个以上的类?

Don't notify() threads. 不要notify()线程。 Notify objects . 通知对象 The "Guarded Blocks" section of the Java Concurrency tutorial explains how wait() and notify() are meant to be used. Java Concurrency教程的“ Guarded Blocks”部分说明如何使用wait()notify() https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html


Usually, you should avoid wait() and notify() altogether. 通常,您应该完全避免使用wait()notify() They are low-level primitive, meant to be used for implementing higher-level synchronization objects. 它们是低级原语,旨在用于实现高级同步对象。 The java.util.concurent package already has quite a few higher-level objects that you can use. java.util.concurent软件包已经具有许多可以使用的更高级别的对象。 That means less work for you to write correct code, and less work for somebody else who needs to understand your code. 这意味着您可以减少编写正确代码的工作,也可以减少需要了解您的代码的其他人的工作。

in the below code, one runnable instance is waiting to get notify... 在下面的代码中,一个可运行实例正在等待获取通知...

You are using an ExecutorService thread-pool but completely missing one of the great features of it. 您正在使用ExecutorService线程池,但完全缺少它的重要功能之一。 When you add a job to the thread-pool, use the submit(...) method which returns a Future object. 将作业添加到线程池时,请使用submit(...)方法,该方法返回Future对象。 You then can call future.get() to wait for the job to complete and return a value. 然后,您可以调用future.get()以等待作业完成并返回值。 You should never need to do your own waiting, etc.. 您永远不需要自己等待,等等。

Future<Void> future = executor.submit(instance);
// now we wait for the thread to complete
future.get();

Also, although it works, it is considered very bad form to call Thread.wait() directly. 另外,尽管它可以工作,但是直接调用Thread.wait()被认为是非常糟糕的形式。 It happens that a notify() is called when the thread finishes but that is an implementation detail that should be relied on. 碰巧在线程完成时会调用notify() ,但这是应该依靠的实现细节。 Either join with a Thread or use the Future.get() above. 使用Thread加入或使用上面的Future.get() Also, if the thread returned before you called wait() you might miss the notify() and your code would never return. 另外,如果线程调用wait() 之前返回,则可能会错过notify()并且代码将永远不会返回。

Lastly, as @vijayraj34 points out, your code is right now single threaded because you submit each job and then immediately wait for it. 最后,正如@ vijayraj34指出的那样,您的代码现在是单线程的,因为您提交了每个作业,然后立即等待它。 What you should be doing is forking all of your threads and saving the Future objects in a collection. 您应该做的是派生所有线程并将Future对象保存在集合中。 Then once you are done starting the jobs you can wait for each Future in turn. 然后,一旦开始工作,您就可以依次等待每个Future

Something like: 就像是:

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 is right but it's best to retrieve futures using a completionService rather than directly so that you can minimize waiting. @Gray是正确的,但是最好使用completionService而不是直接检索期货,这样可以最大程度地减少等待时间。 CompletionService allows you to get the value from a future as future objects become available. 当将来的对象可用时,CompletionService允许您从将来获得价值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM