mszhe的技术分享 人心惟危,道心惟微。惟精惟一,允执厥中。

java异步非阻塞示例


java中执行耗时任务,有时需要线程池、Callable、Future结合使用

  • Callable类
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

public class MyCallable implements Callable<Boolean> {
    private int no;

    public MyCallable(int no) {
        this.no = no;
    }

    @Override
    public Boolean call() throws Exception {
        int sleep = new Random().nextInt(15);
        TimeUnit.SECONDS.sleep(sleep);
        System.out.printf("task #%02d, sleep %ds, ok!\n", no, sleep);
        return Boolean.TRUE;
    }
}

  • Main方法
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public class Main {
    public static void main(String[] args) {
        ExecutorService pool = Executors.newCachedThreadPool();
//        List<Future<Boolean>> list = new ArrayList<>();
        CompletionService<Boolean> cs = new ExecutorCompletionService<>(pool);

        for (int i = 0; i < 15; i++) {
            final int j = i;
//            list.add(pool.submit(new MyCallable(j)));
            cs.submit(new MyCallable(j));
        }

//        for (Future<Boolean> future : list) {
//            try {
//                future.get();
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
        for (int i = 0; i < 15; i++) {
            try {
                cs.take().get();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        pool.shutdown();
    }
}
  • 执行结果如下

  • 结论:future.get();为非阻塞,不会阻塞其它线程执行