Java 如何从工作线程创建和处理消息
如何创建从工作线程到管理线程的异步消息。框架如下。在代码段中,Worker实现Runnable,threadManager是ExecutorService。工作线程长时间运行,应该定期向管理器传递进度消息。一种选择是使用阻塞队列,但我以前没有这样做过Java 如何从工作线程创建和处理消息,java,multithreading,message,Java,Multithreading,Message,如何创建从工作线程到管理线程的异步消息。框架如下。在代码段中,Worker实现Runnable,threadManager是ExecutorService。工作线程长时间运行,应该定期向管理器传递进度消息。一种选择是使用阻塞队列,但我以前没有这样做过 RunnableTester_rev2.threadManager = Executors.newFixedThreadPool( nThreadsAllowed ); final List<Worker> my_ta
RunnableTester_rev2.threadManager = Executors.newFixedThreadPool( nThreadsAllowed );
final List<Worker> my_tasks = new ArrayList<Worker>();
for ( int i = 0; i < nThreadsToRun; i++ )
{
// The Worker thread is created here.
// Could pass a blocking queue to handle messages.
my_tasks.add( new Worker( ) );
}
final List<Future<?>> fList = new ArrayList<Future<?>>();
for ( final Worker task : my_tasks )
{
fList.add( RunnableTester_rev2.threadManager.submit( task ) );
}
RunnableTester_rev2.threadManager.shutdown();
/**
* Are we all done
*/
boolean isDone = false;
/**
* Number of threads finished
*/
int nThreadsFinished = 0;
/**
* Keep processing until all done
*/
while ( !isDone )
{
/*
* Are all threads completed?
*/
isDone = true;
int ii = 0;
nThreadsFinished = 0;
for ( final Future<?> k : fList )
{
if ( !isThreadDoneList.get( ii ) )
{
final boolean isThreadDone = k.isDone();
if ( !isThreadDone )
{
// Reduce printout by removing the following line
// System.out.printf( "%s is not done\n", mywks.get( ii ).getName() );
isDone = false;
}
}
else
{
nThreadsFinished++;
}
ii++;
}
/*
* WOULD LIKE TO PROCESS Worker THREAD MESSAGES HERE
*/
}
RunnableTester\u rev2.threadManager=Executors.newFixedThreadPool(nThreadsAllowed);
最终列表my_tasks=new ArrayList();
对于(int i=0;i();
用于(最终工作任务:我的任务)
{
fList.add(runnabletter_rev2.threadManager.submit(任务));
}
runnabletter_rev2.threadManager.shutdown();
/**
*我们都做完了吗
*/
布尔isDone=false;
/**
*完成的线程数
*/
int nThreadsFinished=0;
/**
*继续处理,直到全部完成
*/
而(!isDone)
{
/*
*所有线程都完成了吗?
*/
isDone=true;
int ii=0;
nThreadsFinished=0;
for(最终未来k:fList)
{
如果(!isThreadDoneList.get(ii))
{
最终布尔值isThreadDone=k.isDone();
如果(!isThreadDone)
{
//通过删除以下行减少打印输出
//System.out.printf(“%s未完成”\n),mywks.get(ii.getName());
isDone=false;
}
}
其他的
{
nThreadsFinished++;
}
ii++;
}
/*
*是否要在此处处理工作线程消息
*/
}
这真的很复杂。我会这样做的
// no need to use a field.
ExecutorService threadManager = Executors.newFixedThreadPool( nThreadsAllowed );
List<Future<Result>> futures = new ArrayList<Future<Result>>();
for ( int i = 0; i < nThreadsToRun; i++ )
// Worker implements Callable<Result>
futures.add(threadManager.submit(new Worker( )));
threadManager.shutdown();
threadManager.awaitTermination(1, TimeUnit.MINUTE);
for(Future<Result> future: futures) {
Result result = future.get();
// do something with the result
}
//不需要使用字段。
ExecutorService threadManager=Executors.newFixedThreadPool(nThreadsAllowed);
列表期货=新的ArrayList();
对于(int i=0;i
我会使用阻塞队列
。您可以尝试以下方法:
final BlockingQueue<Message> q = new LinkedBlockingQueue<Message>();
// start all the worker threads,
// making them report progress by adding Messages into the queue
for (...) {
threadManager.submit(new Runnable() {
// initialize the worker
q.offer(new Message("10% completed"));
// do half of the work
q.offer(new Message("50% completed"));
// do the rest of the work
q.offer(new Message("100% completed"));
});
}
// after starting all the workers, call a blocking retrieval method
// on the queue, waiting for the messages
while (!(everything is done)) {
Message m = q.take();
// process the message
}
CompletionService
保证,一旦您选择了Future
,对其.get()
方法的调用将立即完成:返回结果,或者抛出ExecutionException,封装可调用的引发的异常谢谢您的输入,但我一直在寻找从线程返回的中间消息。如果任务完成后您想立即执行任何操作,请将其添加到任务本身。通过这种方式,它可以同时执行,或者至少以任何顺序执行。你应该在开始这一切的单线程中做最少的工作。在工作线程完成特定的中间进度/结果后,在线程运行时,需要立即处理结果,而不是等到线程完成后再处理。工作线程以小时或天的顺序长时间运行,一整套工作线程的运行时间以周的顺序运行。现在您可以看到需要在工作线程之外完成“一半的工作”,或者处理消息,因为对线程中间结果集有额外的管理。
ExecutorCompletionService<Worker> ecs = new ExecutorCompletionService(executorService);
// Worker has to be a callable
// Now you submit your tasks to the ecs:
for (...) {
ecs.submit(new Worker(...));
}
// Now you block on .take():
while (!(everything is done)) {
Future<Worker> f = ecs.take();
// f.get(), for example, to check the results
}