Callable和Future

Callable和Runnable很像,都是可以创建线程,但是他俩也是有很大的区别的

1.Runnable位于java.lang包下,Callable位于java.util.concurrent包下

2.

Runnable接口中的方法

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

Callable接口中的方法

@FunctionalInterface
public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

3.从上面的方法结果中可以看出

1.Call()方法是有返回值的,run()方法没有

2.call()方法可以抛出异常,而run()方法不能抛出异常

Callable的第一种使用方法

package com.yjc.juc;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.println("执行call()");
        return "callable";
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyCallable myCallable=new MyCallable();
        //利用FutureTask执行Callable并且接受结果
        FutureTask<String> stringFutureTask = new FutureTask<String>(myCallable);
        //利用线程执行Task任务
        new Thread(stringFutureTask).start();
        //接受结果FutureTask.get会发生阻塞情况
        System.out.println("接受的返回值为:"+stringFutureTask.get());

        System.out.println("MyCallable执行完毕,返回值结果正确接收");
    }
}

 

 使用线程池的方式执行call()

package com.yjc.juc;

import java.util.concurrent.*;

public class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.println("执行call()");
        return "callable";
    }
   
 public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyCallable myCallable=new MyCallable();
        //创建一个线程池
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        //创建线程执行任务,接受任务结果
        Future<String> future = executorService.submit(myCallable);
        //接受返回值
        System.out.println(future.get());
        System.out.println("方式二,线程池:MyCallable执行完毕,返回值结果正确接收~");
        //停止线程池
        executorService.shutdown();
    }

注意点,同一个对象的call()方法,即使多个线程调用也只会执行一遍

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        MyCallable myCallable=new MyCallable();
        //利用FutureTask执行Callable并且接受结果
        FutureTask<String> stringFutureTask = new FutureTask<String>(myCallable);
        //利用线程执行Task任务
        new Thread(stringFutureTask).start();
        new Thread(stringFutureTask).start();
        //接受结果FutureTask.get会发生阻塞情况
        System.out.println("接受的返回值为:"+stringFutureTask.get());

        System.out.println("MyCallable执行完毕,返回值结果正确接收");
    }

 

 Future的常用方法

Future.get()方法获取任务执行结果,该方法如果没有返回时,暂时处于阻塞状态
Future.get(Long timeOut,TimeUnit timeUnit)可以设置超时时间
Future.boolean isDone()如果线程结束,无论是正常结束还是任务终止都会返回true
Future.boolean isCanceller()如果任务完成前被取消则返回true
Future.boolean cancel(boolean flag),方法参数如果传入为true代表中断任务,如果任务中断成功,则返回值为true,如果失败则为false

posted @ 2020-03-23 18:12  天戈  阅读(267)  评论(0编辑  收藏  举报