Java 如何从工作线程创建和处理消息

Java 如何从工作线程创建和处理消息,java,multithreading,message,Java,Multithreading,Message,如何创建从工作线程到管理线程的异步消息。框架如下。在代码段中,Worker实现Runnable,threadManager是ExecutorService。工作线程长时间运行,应该定期向管理器传递进度消息。一种选择是使用阻塞队列,但我以前没有这样做过 RunnableTester_rev2.threadManager = Executors.newFixedThreadPool( nThreadsAllowed ); final List<Worker> my_ta

如何创建从工作线程到管理线程的异步消息。框架如下。在代码段中,Worker实现Runnable,threadManager是ExecutorService。工作线程长时间运行,应该定期向管理器传递进度消息。一种选择是使用阻塞队列,但我以前没有这样做过

    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
}