我有一个while循环,用于检查包含要执行的程序的命令的arraylist是否为空。显然它会做一些事情,如果不是空的,但如果它是现在我只有一个Thread.sleep(1000)为其他。这使得与它相互作用的任何东西都相当缓慢。有没有办法让它运行的线程阻塞,直到添加一个新命令? (它运行在它自己的线程中,因此对我来说似乎是最好的解决方案)或者有更好的解决方案吗?
答案 0 :(得分:5)
您可以使用wait()
和notify()
将添加的内容添加到列表中,告知使用者线程有什么要读取的内容。但是,这需要适当的同步等。
但解决问题的更好方法是使用BlockingQueue
代替。根据定义,它们是同步类,并且当添加内容时,出列将适当地阻塞并唤醒。如果您希望队列不受限制,LinkedBlockingQueue
是一个很好的类。如果希望将有限数量的项存储在队列中(或LinkedBlockingQueue
并将一个整数传递给构造函数),则可以使用ArrayBlockingQueue
。如果有限的队列,那么queue.add(...)
将阻塞队列是否已满。
BlockingQueue<Message> queue = new LinkedBlockingQueue<Messsage>();
...
// producer thread(s) add a message to the queue
queue.add(message);
...
// consumer(s) wait for a message to be added to the queue and then removes it
Message message = queue.take();
...
// you can also wait for certain amount of time, returns null on timeout
Message message = queue.poll(10, TimeUnit.MINUTES);
答案 1 :(得分:3)
使用BlockingQueue<E>
作为命令
有一个非常好的例子,说明如何在上面的链接中使用它。
答案 2 :(得分:2)
更好的解决方案是使用ExecutorService。这组合了一个队列和一个线程池。
// or use a thread pool with multiple threads.
ExecutorService executor = Executors.newSingleThreadExecutor();
// call as often as you like.
executor.submit(new Runnable() {
@Override
public void run() {
process(string);
}
});
// when finished
executor.shutdown();