疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

java 多线程Callable和Future


 

前面我们说的线程都是没有返回值的,可以有一个耗时的操作而且要带返回值,当然我们希望如果没有返回值的之前一直阻塞线程直到返回!java 里面操作这样的接口给我们,我们只需要实现callable接口,在call方法实现耗时的操作。执行线程时候会返回一个实现Future接口的对象,Future接口提供get方法拿到Callable执行的返回值。
public class FutureTaskTest {
 
    public static void main(String[] args) {
        Callable<String> callable = new Callable<String>() {  
            public String call() throws Exception {  
                return "Run callable method";  
            }  
        };  
        FutureTask<String> future = new FutureTask<String>(callable);  
        new Thread(future).start();  
        try {  
            Thread.sleep(5000);// 可能做一些事情  
            System.out.println(" println " + future.get());  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        } catch (ExecutionException e) {  
            e.printStackTrace();  
        }  
    }
 
}
FutureTask是实现的Callable接口和Runable接口的类
我们来看下run方法:
public void run() {
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return;
        try {
            Callable<V> c = callable;
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call();
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    setException(ex);
                }
                if (ran)
                    set(result);
            }
        } finally {
            // runner must be non-null until state is settled to
            // prevent concurrent calls to run()
            runner = null;
            // state must be re-read after nulling runner to prevent
            // leaked interrupts
            int s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
 result = c.call();
获取执行的返回,set 方法主要给outcome赋值,当 outcome = v;当调用future.get()方法return 
outcome返回结果!
 
Future接口也可以用于获取线程池的结果:
 ExecutorService threadPool = Executors.newSingleThreadExecutor();  
        Future<String> future = threadPool.submit(new Callable<String>() {  
            public String call() throws Exception {  
                return " ExecutorService run " ;  
            }  
        });  
        try {  
            Thread.sleep(5000);// 可能做一些事情  
            System.out.println(future.get());  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        } catch (ExecutionException e) {  
            e.printStackTrace();  
        }  
submit向线程提交一个callable相当于线程,同时得到带返回值Future对象,Future对象通get方法等到返回值。