Cra*_*lus 7 java concurrency multithreading executorservice executors
我有一系列Runnable要执行的任务(即s)Executor.
每个任务都要求某个条件有效才能继续.我很想知道是否有办法以某种方式配置Executor在队列末尾移动任务,并在条件有效且任务能够执行和完成时尝试执行它们.
所以行为是这样的:
Thread-1从队列中获取任务run并被调用run条件尚未生效Thread-1任务放在队列的末尾,并执行下一个任务Thread-X(来自线程池)从队列条件再次选择任务是有效的并且正在执行任务首先创建执行器。
你有几种可能性。
如果我假设您的任务实现一个简单的接口来查询其状态(类似于带有“NeedReschedule”或“Completed”的枚举),那么Runnable为您的任务实现一个包装器(实现),它将任务和执行器作为实例化参数。该包装器将运行它所绑定的任务,然后检查其状态,并在必要时在终止之前在执行器中重新安排其自身的副本。
或者,您可以使用执行机制向包装器发出信号:必须重新安排任务。这个解决方案更简单,因为它不需要为您的任务提供特定的接口,因此Runnable可以毫无问题地将其简单地放入系统中。然而,异常会导致更多的计算时间(对象构造、堆栈跟踪等)。
这是使用异常信号机制的包装器的可能实现。您需要实现RescheduleException扩展类Throwable,它可以由包装的可运行对象触发(在此设置中的任务不需要更具体的接口)。您还可以使用另一个答案中建议的简单方法RuntimeException,但您必须测试消息字符串才能知道这是否是您正在等待的异常。
public class TaskWrapper implements Runnable {
private final ExecutorService executor;
private final Runnable task;
public TaskWrapper(ExecutorService e, Runnable t){
executor = e;
task = t;
}
@Override
public void run() {
try {
task.run();
}
catch (RescheduleException e) {
executor.execute(this);
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个非常简单的应用程序,随机启动 200 个打包任务,要求重新安排时间。
class Task implements Runnable {
@Override
public void run(){
if (Maths.random() > 0.5)
throw new RescheduleException();
}
}
public class Main {
public static void main(String[] args){
ExecutorService executor = Executors.newFixedThreadPool(10);
int i = 200;
while(i--)
executor.execute(new TaskWrapper(executor, new Task());
}
}
Run Code Online (Sandbox Code Playgroud)
您还可以有一个专用线程来监视其他线程结果(使用消息队列)并在必要时重新安排,但与其他解决方案相比,您会丢失一个线程。