Runnable、Callable和Future

实现多线程的方式有三种方法,

1.继承Thread类

2.实现Runnable接口

3.实现Callable接口

1,2两种方法差不多,Thread类也是实现了Runnable接口的。Runnable接口没有返回值而Callable接口是有返回值的,Callable有点像异步的回调,通过Future接口来接收来自Callable的返回。

package com.lan;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class CallTest {
    static LinkedBlockingQueue<Runnable> quere = new LinkedBlockingQueue<Runnable>();//new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
    static ExecutorService exec = new ThreadPoolExecutor(10,10,0,TimeUnit.SECONDS,quere);
    static LinkedBlockingQueue<Callable> cquere = new LinkedBlockingQueue<Callable>();
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        //        Callable<String> c ;
        //        Future<String> c = exec.submit(new Test());
        //        Object o = c.get();
        //        System.out.println("o-- "+o);
        Future[] f = new Future[10];
        List<Future<String>> list = new ArrayList<Future<String>>(10);
        List<Boolean> ff = new ArrayList<Boolean>(10);
        Callable a = new Test(0);

        for (int i = 0; i < 10; i++) {
            System.out.println(" 加入一个 "+i);
            Callable c = new Test(i);
            list.add(exec.submit(c));
            ff.add(false);
        }
        Boolean complete = false;
        int j = 0;
        while(!complete){
            for (int i = 0; i < 10; i++) {
                if(ff.get(i).equals(false) && list.get(i).isDone() ){
                    j++;
                    ff.set(i, true);
                    System.out.println("--"+list.get(i).get());
                }
            }
            if(j>=10){
                complete = true;
            }
        }
        System.out.println("out of while");
        exec.shutdown();
    }
}

class Test implements Callable<String>{
    private int count;
    public int getCount(){
        return count;
    };
    public Test(int count){
        this.count = count;
    }
    public String call() throws Exception {
        //        Thread.sleep(5000L);
        long start = System.currentTimeMillis();
        while( (System.currentTimeMillis()-start)<1000L ){

        }
        return Thread.currentThread().getName()+"thread count: "+count;
    }


}
 加入一个 0
 加入一个 1
 加入一个 2
 加入一个 3
 加入一个 4
 加入一个 5
 加入一个 6
 加入一个 7
 加入一个 8
 加入一个 9
--pool-1-thread-1thread count: 0
--pool-1-thread-2thread count: 1
--pool-1-thread-3thread count: 2
--pool-1-thread-5thread count: 4
--pool-1-thread-7thread count: 6
--pool-1-thread-9thread count: 8
--pool-1-thread-4thread count: 3
--pool-1-thread-6thread count: 5
--pool-1-thread-8thread count: 7
--pool-1-thread-10thread count: 9
out of while

而FutureObject.get()句柄在执行时,当前线程是会等待线程对象的执行完毕的,所以测试这里用了一个while。所以,如果要使用.get方法时,最好先判断一下isDone。
原文地址:https://www.cnblogs.com/azul0906/p/4214242.html