6.2Java多线程Callable接口

6.2Java多线程Callable接口

Callable接口方法图示

与Runnable接口的run方法比较的优势:

  • Callable接口可以向外抛出异常--->异常监测

  • call方法可以有返回值,run方法没有返回值

与Runnable接口的run方法比较的劣势:

  • 使用起来需要创建执行服务

  • 使用起来需要使用ThreadPool线程池

  • 需要提交到服务里面获取未来的值

  • 再通过get方法返回

  • 最后需要关闭服务

创建线程的方式三:实现callable接口,重写call方法

package iostudy.thread;

import java.util.concurrent.*;

/**
* 使用Callable接口实现图片下载
* @since JDK 1.8
* @date 2021/6/2
* @author Lucifer
*/
public class CDownload implements Callable<Boolean> {
   /*因为使用Callable接口,其接口又返回值。默认是Object,可以通过修改泛型的方式修改返回值类型*/
   /*定义两个属性*/
   private String url; //远程资源路径名称
   private String name; //本地存储资源的名称

   /*构造器*/
   public CDownload(String url, String name){
       this.url = url;
       this.name = name;
  }

   /*重写call方法--->返回泛型数据,抛出异常*/
   public Boolean call() throws Exception{
       WebDownload wd = new WebDownload();
       wd.download(url, name);
       System.out.println(name);
       return true;
  }

   public static void main(String[] args) throws ExecutionException, InterruptedException {
       /*启动call方法的步骤*/
       /*
       1、创建目标对象
       2、创建执行服务
       3、提交执行
       4、获取结果
       5、关闭服务
        */

       //创建目标对象
       CDownload cd1 = new CDownload("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201601%2F29%2F20160129170734_PhxvB.thumb.700_0.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1625197795&t=7f3d142f36283c64779838e6dee5a17e", "GodFather.jpg");
       CDownload cd2 = new CDownload("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg01.sogoucdn.com%2Fapp%2Fa%2F200765%2Fced08837008d4d09bf3f352eaa5bfb4c&refer=http%3A%2F%2Fimg01.sogoucdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1625197866&t=2be2df9616cdfa35271de4b9d407c5e4", "YoungGodFather.jpg");

       //创建执行服务--->两个服务(cd1、cd2)
       ExecutorService service = Executors.newFixedThreadPool(2); //创建线程池中的线程数量

       //提交执行
       Future<Boolean> result1 = service.submit(cd1);
       Future<Boolean> result2 = service.submit(cd2);

       //获取结果--->每一个服务都要获取结果
       boolean r1 = result1.get();
       boolean r2 = result2.get();

       //释放资源--->关闭服务
       service.shutdown();
  }
}

通过callable接口模拟比赛

package iostudy.thread;


import java.util.concurrent.*;

/**
* 模拟比赛,重写call方法,返回整数值
* @since JDK 1.8
* @date 2021/6/2
* @author Lucifer
*/
public class CRacer implements Callable<Integer> {

   /*定义胜利者*/
   private String winner;

   /*重写call方法*/
   @Override
   public Integer call() throws Exception{
       /*循环步数*/
       for (int steps = 1; steps < 100; steps++){
           //模拟兔子休息
           if (Thread.currentThread().getName().equals("rabbit") && steps%10==0){
               /*让线程休眠*/
               Thread.sleep(100);
          }
           /*输出每个代理商的步数*/
           System.out.println();
           //判断比赛是否结束
           boolean flag = gameOver(steps);
           if (flag){
               /*返回步数*/
               return steps;
          }
      }
       return null;
  }

   /**
    * 胜利条件判断的方法
    * @param steps     步数
    * @return
    */
   public boolean gameOver(int steps){
       if (winner!=null){
           /*存在胜利者,返回真*/
           return true;
      }else {
           /*先到达一百步的人*/
           if (steps == 100){
               /*获得胜利者的名字*/
               winner = Thread.currentThread().getName();
               /*输出*/
               System.out.println("Winner is:" + winner);
               /*返回真*/
               return true;
          }
      }
       return false;
  }

   /**
    * 主线程启动方法
    */
   public static void main(String[] args) throws ExecutionException, InterruptedException {
       /*启动call方法的步骤*/
       /*
       1、创建目标对象
       2、创建执行服务
       3、提交执行
       4、获取结果
       5、关闭服务
        */

       /*创建目标对象--->实现类对象*/
       CRacer cRacer = new CRacer();

       /*创建执行服务*/
       ExecutorService service = Executors.newFixedThreadPool(2); //使用线程池方法执行服务

       /*提交执行*/
       Future<Integer> result1 = service.submit(cRacer);
       Future<Integer> result2 = service.submit(cRacer);

       /*获取结果*/
       Integer r1 = result1.get();
       Integer r2 = result2.get();
       System.out.println(r1 + "--->" + r2);

       /*关闭服务*/
       service.shutdown();
  }
}

 

It's a lonely road!!!
原文地址:https://www.cnblogs.com/JunkingBoy/p/14842863.html