CompletionService

CompletionService接口:

将生产新的异步任务与使用已完成任务的结果分离开来的服务。生产者 submit 执行的任务。使用者 take 已完成的任务,并按照完成这些任务的顺序处理它们的结果。例如,CompletionService 可以用来管理异步 IO ,执行读操作的任务作为程序或系统的一部分提交,然后,当完成读操作时,会在程序的不同部分执行其他操作,执行操作的顺序可能与所请求的顺序不同。

import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
* 演示CompletionService的使用
*
* @author Administrator
*
*/

public class CompletionServiceTest {
private static final ExecutorService exec = Executors
    .newFixedThreadPool(10);

public static void main(String[] args) throws InterruptedException,
    ExecutionException {
   CompletionService<Integer> cs = new ExecutorCompletionService<Integer>(
     exec);
   final int nums[] = { 1 };
   for (int i = 0; i < 5; i++) {//提交五个任务
    cs.submit(new Callable<Integer>() {
     public Integer call() throws Exception {
      Thread.sleep(nums[0] * 1000);
      ++nums[0];
      return nums[0];
     }
    });
    // System.out.println(nums[0]);
   }

   for (int i = 0; i < 5; i++) {//得到五个任务
    Future<Integer> f = cs.take();
    System.out.println(f.get());
   }
   exec.shutdown();
}

}

运行程序却发现会有如下结果:

2
2
3
5
4

上边是一次运行结果,也就说不同的任务返回了相同的值。分析原因,是由++nums[0];的非原子性导致的。

将其加锁,把提交任务的部分改为:

   for (int i = 0; i < 5; i++) {//提交五个任务
    cs.submit(new Callable<Integer>() {
     public Integer call() throws Exception {
      Thread.sleep(nums[0] * 1000);
      synchronized(nums){
       ++nums[0];
      }
      return nums[0];
     }
    });
    // System.out.println(nums[0]);
   }

运行结果:

2
3
4
5
6
。问题解决

posted @ 2010-04-08 18:20  macula7  阅读(368)  评论(0编辑  收藏  举报