美文网首页
Java并发:Callable异步回调Future、Future

Java并发:Callable异步回调Future、Future

作者: PC_Repair | 来源:发表于2018-08-04 10:29 被阅读144次
简单说明:
  • Callable接口类似于Runnable,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到。
  • FutureTask实现了两个接口,Runnable和Future,所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。假设有一个很耗时的返回值需要计算,并且这个返回值不是立刻需要的话,那么就可以使用这个组合,用另一个线程去计算返回值,而当前线程在使用这个返回值之前可以做其它的操作,等到需要这个返回值时,再通过Future得到。
Callable说明:

Callbale接口是一个参数化的类型,只有一个方法call。

public interface Callable<V>
{
  V call() throw Exception;
}
  • 类型参数是返回值的类型。例如,Callable<Integer>表示一个最终返回Integer的异步计算。
Future用法:

java.util.concurrent.Future 是一个异步回调接口,保存异步计算的结果。

  • Future接口具有下面方法:
public interface Future<V>
{
  V get() throws ...;
  V get(long timeout, TimeUnit unit) throws ...;
  void cancel(boolean mayInterrupt);
  boolean isCancelled();
  boolean isDone();
}

用例:

public class CallableFuture {

    public static void main(String[] args) throws InterruptedException, Exception {
        ExecutorService exec = Executors.newCachedThreadPool();
        // Future是一个接口,该接口用来返回异步的结果。
        Future<String> st = exec.submit(new TaskCallable());
        System.out.println("finished");
    }
}

class TaskCallable implements Callable<String> {

    public String call() throws Exception {
        Thread.sleep(2000);
        return "callstatus=OK";
    }
}

java.util.concurrent.Future<V>

  • V get()
  • V get(long time, TimeUnit unit)
    获取结果,如果没有结果可用,则阻塞直到真正得到结果超过指定的时间为止。如果不成功,第二个方法会抛出TimeoutException异常。
  • boolean cancel(boolean mayInterrupt)
    尝试取消一任务的运行。如果任务已经开始,并且mayInterrupt参数值为true,它就会被中断。如果成功执行了取消操作,返回true。
  • boolean isCancelled()
    如果任务在完成前被取消了,则返回true。
  • boolean isDone()
    如果任务结束,无论是正常结束、中途取消或发生异常,都返回true。
FutureTask用法:

FutureTask实现了java.util.concurrent.RunnableFuture<V>接口,实际上实现了Runnable和 Future<V>两个接口。

java.util.concurrent.FutureTask<V>

  • FutureTask(Callable<V> task)
  • FutureTask(Runnable task, V result)
    构造一个既是Future<V>又是Runnable的对象。

用例:

public class MyFutureTask {
    
    public static void main(String[] args) {
        
        Callable<int[]> primeCallable = new PrimeCallable(1000);
        
        FutureTask<int[]> primeTask = new FutureTask<int[]>(primeCallable);
        
        Thread t = new Thread(primeTask);
        
        t.start();
        
        try {
            // 假设现在做其他事情 
            Thread.sleep(5000);
 
            // 回来看看质数找好了吗
            if (primeTask.isDone()) {
                int[] primes = primeTask.get();
                for (int prime : primes) {
                    System.out.print(prime + " ");
                }
                System.out.println();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
 
class PrimeCallable implements Callable<int[]> {
    private int max;
 
    public PrimeCallable(int max) {
        this.max = max;
    }
 
    public int[] call() throws Exception {
        int[] prime = new int[max + 1];
 
        List<Integer> list = new ArrayList<Integer>();
 
        for (int i = 2; i <= max; i++)
            prime[i] = 1;
 
        for (int i = 2; i * i <= max; i++) { // 这里可以改进
            if (prime[i] == 1) {
                for (int j = 2 * i; j <= max; j++) {
                    if (j % i == 0)
                        prime[j] = 0;
                }
            }
        }
 
        for (int i = 2; i < max; i++) {
            if (prime[i] == 1) {
                list.add(i);
            }
        }
 
        int[] p = new int[list.size()];
        for (int i = 0; i < p.length; i++) {
            p[i] = list.get(i).intValue();
        }
 
        return p;
    }
}

相关文章

网友评论

      本文标题:Java并发:Callable异步回调Future、Future

      本文链接:https://www.haomeiwen.com/subject/zjvpvftx.html