Java - 等待和通知的理想使用? [英] Java - Ideal use of wait and notify?

查看:48
本文介绍了Java - 等待和通知的理想使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到目前为止,这段代码在测试中似乎运行良好.但是,我是多线程方面的新手,想知道这段代码是否理想,因为我知道有很多关于并发的错误".
有没有更好的方法可以在单个线程上为排队的 Runnable 制作执行程序?这是我第一次制作,所以我倾向于相信可以做得更好.

This code seems to work fine so far in testing. However I am new at multithreading and want to know if this code is ideal, since I know there is a lot of "donts" regarding concurrency.
Is there a better way to make an executor for queued Runnables on a single thread? This is my first time making one so I feel inclined to believe something could be better.

public class ExplosionExecutor{
private static List<Runnable> queue= new ArrayList<Runnable>();

private static Thread thread= new Thread(new Runnable() {
    public void run() {
        while(true){
            Runnable[] queuedump;
            synchronized (queue) {
                if(queue.size()==0){
                    try {
                        queue.wait();
                    } catch (InterruptedException e){e.printStackTrace();}
                }

                queuedump= queue.toArray(new Runnable[0]);
                queue.clear();  
            }
            for(Runnable r : queuedump)
                r.run();
        }
    }

}, "Nuke Explosions");
static{
    thread.start();
}

public static void execute(Runnable command) {
    synchronized (queue) {
        queue.add(command);
        queue.notify();
    }
}

}

推荐答案

没关系 - 是的.

最好不要重新发明轮子.

It's best not to reinvent the wheel.

1) 有阻塞队列,它们具有等待新项目的方法并且已经同步:

1) There are blocking queues which have methods to wait for new items and are already synchronized:

public static void main(String[] args) throws Exception {
    final BlockingQueue<Runnable> r = new LinkedBlockingQueue<>();
    final Thread t = new Thread(new Runnable() {

        @Override
        public void run() {
            while (true) {
                try {
                    r.take().run();
                } catch (InterruptedException ex) {
                    return;
                }
            }
        }
    });
    r.add(new Runnable() {

        @Override
        public void run() {
            //do stuff
        }
    });
}

2) ExecutorService API 封装了所有这些行为:

2) There is the ExecutorService API which encapsulates all this behaviour:

public static void main(String[] args) throws Exception {
    final ExecutorService es = Executors.newSingleThreadExecutor();
    es.execute(new Runnable() {

        @Override
        public void run() {
            //do stuff
        }
    });
}

3) 如果您想检查提交的任务是否成功和/或等待汇总的任务完成,则无法使用 API 执行此操作.使用 ExecutorService,您可以非常轻松地做到这一点.

3) If you want to check the success of the submitted task and/or wait for a sumbitted task to finish you cannot do that using your API. With the ExecutorService you can do this very easily.

public static void main(String[] args) throws InterruptedException {
    final ExecutorService es = Executors.newSingleThreadExecutor();
    final Future<?> f = es.submit(new Runnable() {

        @Override
        public void run() {
            //do stuff
        }
    });
    try {
        //wait
        f.get();        
    } catch (ExecutionException ex) {
        //there was an exeception in the task
    }
}

最后要注意的是,您实现代码的方式无法停止消费者线程.

A final note is that the way you have implemented your code there is no way to stop the consumer thread.

在我的第一个示例中,您需要手动调用 t.interrupt() 并且由于我的实现,这会导致线程退出.在第二个/第三个示例中,您需要调用 ExecutorService.shutdown() 来停止使用者线程.

In my first example you would need to manually call t.interrupt() and because of my implementation this would case the thread to exit. In the second/third examples you would need to call ExecutorService.shutdown() to stop the consumer threads.

如果你不停止线程,那么你的程序不会退出,除非它们是守护进程.

If you do not stop the threads then your program will not exit unless they are daemon.

这篇关于Java - 等待和通知的理想使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆