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

问题描述 投票:0回答:3

在下面的代码中,一个可运行实例正在等待接收通知。如何通过其他线程通知该线程我应该使用方法或另一个包含要通知的线程的类..我被困在这里请帮忙...

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

        }

    }

}
java multithreading concurrency java.util.concurrent
3个回答
1
投票

我应该使用方法还是另一个包含线程来通知的类?

不要

notify()
线程。通知对象。 Java 并发教程的“受保护的块”部分解释了如何使用
wait()
notify()
https://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html


通常,您应该完全避免

wait()
notify()
。它们是低级原语,旨在用于实现更高级别的同步对象。
java.util.concurent
包已经有很多可以使用的高级对象。这意味着您编写正确代码的工作量减少了,其他需要理解您代码的人的工作量也减少了。


0
投票

在下面的代码中,一个可运行实例正在等待接收通知...

您正在使用

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(); }



0
投票

© www.soinside.com 2019 - 2024. All rights reserved.