I'v got ConcurrentLinkedDeque which I'm using for synchronic push/pop elements, and I'v got some async tasks which are taking one element from stack and if this element has neighbors It's pushing it to stack.
我有一个ConcurrentLinkedDeque,我用它来做同步推送/流行元素,我有一些异步任务,从堆栈中获取一个元素,如果这个元素有邻居,它就把它推到堆栈上。
Example code:
示例代码:
private ConcurrentLinkedDeque<Item> stack = new ConcurrentLinkedDeque<>();
private ExecutorService exec = Executors.newFixedThreadPool(5);
while ((item = stack.pollFirst()) != null) {
if (item == null) {
} else {
Runnable worker = new Solider(this, item);
exec.execute(worker);
}
}
class Solider{
public void run(){
if(item.hasNeighbors){
for(Item item:item.neighbors){
stack.push(item)
}
}
}
}
I would like to have additional statement in while loop which answers the question - "any task in Executor is working?"
我想在while循环中有更多的语句来回答这个问题——“Executor中的任何任务都在工作吗?”
1 个解决方案
#1
28
There isn't a clean way to check if all Runnables are done if you use ExecutorService.execute(Runnable)
. Unless you build a mechanism to do so in the Runnable itself (which is sloppy in my opinion).
如果您使用ExecutorService.execute(Runnable),那么没有一种干净的方法来检查所有Runnables是否已经完成。除非您构建一种机制来在Runnable本身中实现这一点(在我看来这是草率的)。
Instead:
Use ExecutorService.submit(Runnable)
. This method will return a Future<?>
which is a handle to the result of a runnable. Using Futures provides a clean way to check results.
相反:使用ExecutorService.submit(可运行)。此方法将返回一个Future 是一个可运行结果的句柄。使用期货提供了一种检验结果的干净方式。
All you have to do is maintain a list of Futures that you submit, and then you can iterate over the whole list of Futures and either:
A) wait for all the futures to be done in a blocking way or
B) check if all the futures are done in a non-blocking way.
所有你要做的就是保持一个期货,你提交的清单,然后就可以遍历整个列表的期货和:a)等所有的期货以阻塞方式做或B)检查是否所有的期货以非阻塞的方式进行。
Here is a code example:
下面是一个代码示例:
List<Future<?>> futures = new ArrayList<Future<?>>();
ExecutorService exec = Executors.newFixedThreadPool(5);
// Instead of using exec.execute() use exec.submit()
// because it returns a monitorable future
while((item = stack.pollFirst()) != null){
Runnable worker = new Solider(this, item);
Future<?> f = exec.submit(worker);
futures.add(f);
}
// A) Await all runnables to be done (blocking)
for(Future<?> future : futures)
future.get(); // get will block until the future is done
// B) Check if all runnables are done (non-blocking)
boolean allDone = true;
for(Future<?> future : futures){
allDone &= future.isDone(); // check if future is done
}
#1
28
There isn't a clean way to check if all Runnables are done if you use ExecutorService.execute(Runnable)
. Unless you build a mechanism to do so in the Runnable itself (which is sloppy in my opinion).
如果您使用ExecutorService.execute(Runnable),那么没有一种干净的方法来检查所有Runnables是否已经完成。除非您构建一种机制来在Runnable本身中实现这一点(在我看来这是草率的)。
Instead:
Use ExecutorService.submit(Runnable)
. This method will return a Future<?>
which is a handle to the result of a runnable. Using Futures provides a clean way to check results.
相反:使用ExecutorService.submit(可运行)。此方法将返回一个Future 是一个可运行结果的句柄。使用期货提供了一种检验结果的干净方式。
All you have to do is maintain a list of Futures that you submit, and then you can iterate over the whole list of Futures and either:
A) wait for all the futures to be done in a blocking way or
B) check if all the futures are done in a non-blocking way.
所有你要做的就是保持一个期货,你提交的清单,然后就可以遍历整个列表的期货和:a)等所有的期货以阻塞方式做或B)检查是否所有的期货以非阻塞的方式进行。
Here is a code example:
下面是一个代码示例:
List<Future<?>> futures = new ArrayList<Future<?>>();
ExecutorService exec = Executors.newFixedThreadPool(5);
// Instead of using exec.execute() use exec.submit()
// because it returns a monitorable future
while((item = stack.pollFirst()) != null){
Runnable worker = new Solider(this, item);
Future<?> f = exec.submit(worker);
futures.add(f);
}
// A) Await all runnables to be done (blocking)
for(Future<?> future : futures)
future.get(); // get will block until the future is done
// B) Check if all runnables are done (non-blocking)
boolean allDone = true;
for(Future<?> future : futures){
allDone &= future.isDone(); // check if future is done
}