并发问题和实现Callable接口

发布时间 2023-08-24 15:30:58作者: Y~~~

并发

1.初识并发问题
// 多个线程同时操作一个对象
// 买火车票
// 发现问题:多个线程操作同一个资源的情况下,线程不安全
public class TestThread4 implements Runnable{
   // 票数
   private int ticketNums = 10;

   public void run(){
       while (true){
           if (this.ticketNums <= 1){
               break;
          }
           // 模拟延时
           try {
               Thread.sleep( 200);
          } catch (Exception e) {
               e.printStackTrace();
          }

           System.out.println(Thread.currentThread().getName()+"---->拿到了第"+ticketNums+"————>票");
           this.ticketNums--;
      }
  }

   public static void main(String[] args) {
       TestThread4 ticket = new TestThread4();
       new Thread(ticket,"小明").start();
       new Thread(ticket,"老师").start();
       new Thread(ticket,"黄牛").start();
  }

}
2.龟兔赛跑案例
// 模拟龟兔赛跑
public class Race implements Runnable{
   // 定义胜利者
   private static  String winner;

   @Override
   public void run() {
       for (int i = 0; i <= 100; i++) {
           // 模拟兔子休息
           if(Thread.currentThread().getName() == "兔子"){
               try {
                   Thread.sleep(100);
              } catch (InterruptedException e) {
                   e.printStackTrace();
              }
          }

           // 判断比赛是否结束
           boolean flag = this.gameOver(i);
           //如果比赛结束
           if(flag){
               break;
          }
           System.out.println(Thread.currentThread().getName() + "---->跑了"+i+"步");
      }
  }
   private boolean gameOver(int step){
       // 判断是否有胜利者
       if(winner !=null){
           return  true;
      }else {
           if(step >= 100){
               winner = Thread.currentThread().getName();
               System.out.println("winner is" +winner);
               return true;
          }
           return false;
      }
  }

   // 判断是否完成比赛
   public static void main(String[] args) {
       Race race = new Race();
       new Thread(race,"兔子").start();
       new Thread(race,"乌龟").start();
  }
}
3.实现Callable接口
  1. 实现Callable接口,需要返回值类型。

  2. 重写call方法,需要抛出异常。

  3. 创建目标对象。

  4. 创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(1);

  5. 提交执行:Future<Boolean> result1 = ser.submit(t1);

  6. 获取结果: boolean r1 = result1.get()

  7. 关闭服务:ser.shutdownNow();

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;

// 线程实现方式三
public class TestCallable implements Callable<Boolean> {
   private String url; //地址
   private String name;//文件名

   public TestCallable(String url, String name) {
       this.url = url;
       this.name = name;
  }

   // 下载图片线程执行体
   @Override
   public Boolean call() {
       WebDownLoader webDownloader = new WebDownLoader();
       webDownloader.downLoader(url, name);
       System.out.println("下载了文件名为:" + name);
       return true;
  }

   public static void main(String[] args) throws ExecutionException, InterruptedException {
       TestCallable t1 = new TestCallable("https://img0.baidu.com/it/u=3021883569,1259262591&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1692982800&t=5858b3800995bb2c1af459caaab34932", "1.jpg");
       TestCallable t2 = new TestCallable("https://img0.baidu.com/it/u=3021883569,1259262591&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1692982800&t=5858b3800995bb2c1af459caaab34932", "2.jpg");
       TestCallable t3 = new TestCallable("https://img0.baidu.com/it/u=3021883569,1259262591&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1692982800&t=5858b3800995bb2c1af459caaab34932", "3.jpg");

       // 创建执行服务
       ExecutorService ser = Executors.newFixedThreadPool(3);

       // 提交换行
       Future<Boolean> r1 = ser.submit(t1);
       Future<Boolean> r2 = ser.submit(t2);
       Future<Boolean> r3 = ser.submit(t3);

       // 获取结果
       boolean rs1 = r1.get();
       boolean rs2 = r2.get();
       boolean rs3 = r3.get();

       // 关闭服务
       ser.shutdownNow();
  }
   public static void downLoader(String url, String name) {

       try {
           FileUtils.copyURLToFile(new URL(url), new File(name));
      } catch (IOException e) {
           e.printStackTrace();
           System.out.println("Io异常,downloader出现问题");
      }
  }
}

// 下载器
class WebDownLoader {
   // 下载方法
   public void downLoader(String url, String name) {
       try {
           FileUtils.copyURLToFile(new URL(url), new File(name));
      } catch (IOException e) {
           e.printStackTrace();
           System.out.println("Io异常,downloader出现问题");
      }
  }
}