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。