zoukankan      html  css  js  c++  java
  • Callable的Future模式

    线程实现方式:
    1.继承Thread类
    2.实现Runnable接口
    3.线程池
    4.Callable

    无论使用继承Thread类还是实现Runnable接口,还是使用线程池都没有办法解决2个问题
    1.线程执行没有返回值结果
    2.线程执行没有办法抛出异常,只能自己通过try-catch解决

    Callable和Runnable类似,在JUC包下,主要区别在于Callable中的call方法可以带返回值并且可以抛出异常
    如果需要执行Callable,需要Future实现类的支持,能够接受返回值结果,FutureTask是Future实现类

    调用Callable的第一种实现方案:

    public class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
    System.out.println("Callable接口中重写的Call方法,可以有返回值并且抛出异常");
    return "callable";
    }
    
    public static void main(String[] args) throws ExecutionException, InterruptedException {
    MyCallable myCallable=new MyCallable();
    //利用FutureTask执行Callable并且接受结果
    FutureTask<String> stringFutureTask = new FutureTask<>(myCallable);
    //利用线程执行Task任务
    new Thread(stringFutureTask).start();
    //接受结果FutureTask.get会发生阻塞情况
    System.out.println(stringFutureTask.get());
    
    System.out.println("MyCallable执行完毕,返回值结果正确接收~");
    }
    }


    调用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(2000,TimeUnit.MILLISECONDS));
    System.out.println("方式二,线程池:MyCallable执行完毕,返回值结果正确接收~");
    //停止线程池
    executorService.shutdown();
    }


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

    Future提供三种功能:1.中断任务cancel(true) 2.判断任务是否执行完成isDone() 3.获取任务执行后的结果get()
    //中断任务
    boolean cancel = future.cancel(true);
    if(cancel){
    System.out.println("中断任务成功~");
    }else{
    //接受返回值
    System.out.println(future.get(2000,TimeUnit.MILLISECONDS));

    }
    如果让手写Future模式应该怎么样定义?
    wait负责阻塞和notify负责唤起阻塞线程

    public class MyFuture {
    //FLAG相当于数据标识,如果放入数据成功,则返回为true,否则返回为false
    private static boolean FLAG=false;
    private String data;
    
    public synchronized void setData(String data) throws InterruptedException {
    Thread.sleep(2000);
    //赋值操作
    this.data = data;
    FLAG=true;
    //唤起
    notify();
    }
    
    public synchronized String getData() {
    //如果获取数据失败
    if(!FLAG){
    try {
    wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    return data;
    }
    
    public static void main(String[] args) {
    MyFuture future=new MyFuture();
    new Thread(()->{
    try {
    future.setData("张三");
    System.out.println(future.getData());
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }).start();
    }
    }
  • 相关阅读:
    构造函数
    时延(delay,latency)
    吞吐量
    带宽(band-width)
    单位
    bps
    比特(bit)
    速率
    C语言中的“>>”和“<<”
    C#中unit
  • 原文地址:https://www.cnblogs.com/danxun/p/12552948.html
Copyright © 2011-2022 走看看