crushS  

多线程(01)

创建线程方法一

  • 自定义线程类继承Thread

  • 重写run()方法,编写线程执行体

  • 创建线程对象,调用start()方法启动线程

package com.kuang.ThreadLesson;
//线程开启不一定立即执行,由CPU调度执行
public class TestThread01 extends Thread{
   @Override
   public void run() {
       // run()方法线程体
       for (int i = 0; i < 20; i++) {
           System.out.println("顺利见面---"+i);
      }
  }

   public static void main(String[] args) {
       //创建一个线程对象
       TestThread01 p = new TestThread01();
       // 调用start()方法开启线程
       p.start();
       for (int i = 0; i < 20; i++) {
           System.out.println("一切顺利--"+i);
      }
  }
}

实现多线程同步下载图片

package com.kuang.ThreadLesson;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;

// 实现多线程同步下载图片
public class TestThread02 extends Thread{
   private String url;
   private String name;
   public TestThread02(String url,String name){
       this.url = url;
       this.name = name;
  }
   // 下载图片线程的执行体
   @Override
   public void run() {
       WebDownloader webDownload = new WebDownloader();
       webDownload.downloader(url,name);
       System.out.println("下载了文件名为:"+name);
  }

   public static void main(String[] args) {
       TestThread02 t1 = new TestThread02("\thttps://tse4-mm.cn.bing.net/th/id/OIP-C.Rnxb_gFn8661u6XOEjqIDAHaHF?pid=ImgDet&rs=1","t1.jpg");
       TestThread02 t2 = new TestThread02("\thttps://pic3.zhimg.com/v2-44469066400f7f9f5e70f6482c793731_r.jpg?source=1940ef5c","t2.jpg");
       TestThread02 t3 = new TestThread02("\thttps://tse1-mm.cn.bing.net/th/id/R-C.692f6c37f48a…NvDd%2fRRpuTzfIy4P9%2bS1k%3d&risl=&pid=ImgRaw&r=0","t3.jpg");
       t1.start();
       t2.start();
       t3.start();
  }
}
// 下载器
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方法出现问题");
      }
  }
}

创建多线程方法二

  • 定义类实现Runnable接口

  • 实现run()方法

  • 创建线程对象,调用start()方法启动线程

小结

  • 继承Thread类

    • 子类继承Thread类具备多线程能力

    • 启动线程:子类对象.start()

    • 不建议使用:避免OPP单继承局限性

  • 实现Runnable接口

    • 实现接口Runnable具有多线程能力

    • 启动线程:传入目标对象+Thread对象.start()

    • 推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用

 

多个线程同时操作同一个对象

package com.kuang.ThreadLesson;

// 多个线程同时操作同一个对象
// 买火车票的例子
// 发现问题:多个线程操作同一个资源的情况下,线程不安全,数据紊乱
public class TestThread04 implements Runnable{

   //票数
   private int ticketNumber = 10;
   @Override
   public void run() {
       while(true){
           if(ticketNumber<=0){
               break;
          }
           // 模拟延时
           try {
               Thread.sleep(200);
          } catch (InterruptedException e) {
               e.printStackTrace();
          }
           System.out.println(Thread.currentThread().getName()+"买到了第"+ticketNumber--+"张票");
      }
  }

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

龟兔赛跑

package com.kuang.ThreadLesson;

// 模拟龟兔赛跑
public class Race implements Runnable{
   // 胜利者
   private static String winner;

   @Override
   public void run() {
       for (int i = 0; i <= 100; i++) {
           // 模拟兔子睡觉
           if(Thread.currentThread().getName()=="兔子"&&i%10==0){
               try {
                   Thread.sleep(1);
              } catch (InterruptedException e) {
                   e.printStackTrace();
              }
          }
           // 判断比赛是否结束
           boolean flag = gameOver(i);
           if(flag){
               break;
          }
           System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
      }
  }
   // 判断是否完成比赛
   private boolean gameOver(int steps){
       // 判断是否有胜利者
       if(winner!=null){// 已经存在胜利者
           return true;
      }{
           if(steps>=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();
  }
}

 

实现Callable接口

  1. 实现Callable接口,需要返回值类型

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

  3. 创建目标对象

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

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

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

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

package com.kuang.Demo02;

import jdk.nashorn.internal.codegen.CompilerConstants;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;
//线程创建方式三:实现Callable接口
/*
Callable的好处
1.可以定义返回值
2.可以抛出异常
*/
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 webDownload = new WEbDownloader();
       webDownload.downloader(url,name);
       System.out.println("下载了文件名为:"+name);
       return true;
  }

   public static void main(String[] args) throws ExecutionException, InterruptedException {
       TestCallable t1 = new TestCallable("\thttps://tse4-mm.cn.bing.net/th/id/OIP-C.Rnxb_gFn8661u6XOEjqIDAHaHF?pid=ImgDet&rs=1","t1.jpg");
       TestCallable t2 = new TestCallable("\thttps://pic3.zhimg.com/v2-44469066400f7f9f5e70f6482c793731_r.jpg?source=1940ef5c","t2.jpg");

       //1. 创建执行服务
       ExecutorService ser = Executors.newFixedThreadPool(2);
       //2. 提交执行
       Future<Boolean> result1 = ser.submit(t1);
       Future<Boolean> result2 = ser.submit(t2);
       //3. 获取结果
       boolean r1 = result1.get();
       boolean r2 = result2.get();
       //4. 关闭服务
       ser.shutdownNow();



  }
}
// 下载器
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方法出现问题");
      }
  }
}

 

posted on 2021-08-18 15:53  crushS  阅读(207)  评论(0编辑  收藏  举报