关于线程的创建问题

本文介绍了Java中实现多线程的三种方式:继承Thread类、实现Runnable接口以及实现Callable接口。通过示例代码详细展示了如何创建线程、执行线程任务,并解释了它们之间的区别和使用场景。内容涵盖线程同步问题、线程安全以及结果返回等概念。
摘要由CSDN通过智能技术生成

多线程

线程创建

1.Thread class

​ 继承Thread类,Thread类实现Runnable接口

  • (1)自定义线程类继承Thread类
  • (2)重写run() 方法,编写线程执行体
  • (3)创建线程对象,调用start() 方法启动线程
//线程开始不一定立即执行,要看CPU的调度

//创建线程  继承Thread类  不建议,避免OOP单继承的局限性
public class TestThread extends Thread{

    //重写run方法
    @Override
    public void run() {
        //run方法线程体
        for (int i=0;i<5;i++){
            System.out.println("run"+i);
        }
    }

    public static void main(String[] args) {
        //main线程,主线程
        for (int i=0;i<6;i++){
            System.out.println("main"+i);
        }

        //创建线程对象
        TestThread testThread = new TestThread();
        //调用start()方法
        testThread.start();   //与主线程同时执行
//        testThread.run();  //执行run  不同时
    }
}

  • 案例:下载图片例子
import java.io.File;
import java.io.IOException;
import java.net.URL;

//Download the pictures
//1.继承Thread
public class TestThread02 extends Thread{

    private String url;  //网络图片的地址
    private String name;  //将要保存的文件名

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


    //3.重写run方法
    @Override
    public void run() {
        //下载图片线程的之喜提
        WebDownloader webDownloader = new WebDownloader();
        webDownloader.download(url,name);
        System.out.println("download name:"+name);
    }

    //主线程main
    public static void main(String[] args) {
        TestThread02 t1 = new TestThread02("https://hao1.qhimg.com/t01ea3a44e231e5d6f4.png","1.png");
        TestThread02 t2 = new TestThread02("https://mvnrepository.com/img/1db2323c3992372f3dc1a4729ff507c5","2.png");
        TestThread02 t3 = new TestThread02("https://p1.ssl.qhimg.com/dr/270_500_/t019c311710c700e6dd.jpg?size=800x450","3.png");

        t1.start();
        t2.start();
        t3.start();

    }
}


//2.创建下载器
class WebDownloader{

    //下载方法
    public void download(String url,String name){
        try{
            //FileUtils工具类 url 网站   file文件名
            FileUtils.copyURLToFile(new URL(url),new File(name));
        }catch (IOException e){
            e.printStackTrace();
            System.out.println("downloader方法出现问题");
        }
    }
}

2.Runnable接口

​ 实现Runnable接口

  • (1)定义一个类实现Runnable接口

  • (2)实现run()方法,编写线程执行体

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

    //1.实现Runnable接口
    public class TestThread03 implements Runnable{
        //2.重写run方法
        @Override
        public void run() {
            //run方法线程体
            for (int i=0;i<5;i++){
                System.out.println("run"+i);
            }
        }
    
        public static void main(String[] args) {
            //main线程,主线程
            for (int i=0;i<6;i++){
                System.out.println("main"+i);
            }
    
            //创建Runnable接口实现对象
            TestThread03 testThread03 = new TestThread03();
    
            //创建线程对象,通过线程对象来开启线程  代理
            Thread thread = new Thread(testThread03);
    
            //调用start()方法
            thread.start();   //与主线程同时执行
    
        }
    }
    
    
  • 案例:抢火车票问题

    //多个线程操作同样一个对象
    //买火车票例子
    
    //问题:多个线程同时操通一个对象时,线程不安全,数据紊乱
    //1.实现Runnable接口
    public class TestThread04 implements Runnable{
    
        private int ticketNums=10;//票数
    
        @Override
        public void run() {
            while (true){
    
                if (ticketNums<=0){
                    break;
                }
    
                //Thread.currentThread().getName() 获得当前线程执行的名字
                System.out.println(Thread.currentThread().getName()+"拿到了"+ticketNums--+"票");
    
            }
        }
    
        public static void main(String[] args) {
            TestThread04 testThread04 = new TestThread04();
    
            //创建三个线程
            new Thread(testThread04,"你").start();
            new Thread(testThread04,"我").start();
            new Thread(testThread04,"黄牛").start();
        }
    }
    
    
    • 案例:模拟龟兔赛跑

      //模拟龟兔赛跑
      public class Race implements Runnable{
      
          //胜利者
          private static String winner;
      
          @Override
          public void run() {
              for (int i = 0; i <=100 ; i++) {
      
                  if (Thread.currentThread().getName().equals("rabbit")&&(i+1)%10==0){  //模拟兔子休息
                      try {
                          Thread.sleep(2);
                      } 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)  //已经存在winner
                  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) {
              //多个线程操作同样一个对象
              Race  race= new Race();  //赛道
      
              new Thread(race,"tortoise").start();
              new Thread(race,"rabbit").start();
      
          }
      }
      
      

3.Callable接口

​ 实现Callable接口

  • (1)实现Callable接口

  • (2)重写call方法,抛出异常

  • (3)创建目标对象

  • (4)创建执行任务:

  • (5)提交执行任务

  • (6)获取结果

  • (7)关闭服务

    import org.apache.commons.io.FileUtils;
    
    import java.io.File;
    import java.io.IOException;
    import java.net.URL;
    import java.util.concurrent.*;
    
    
    //1.实现Callable接口
    //定义返回值
    //抛出异常
    public class TestThread05 implements Callable<Boolean> {
    
    
        private String url;  //网络图片的地址
        private String name;  //将要保存的文件名
    
        public TestThread05(String url,String name){
            this.name=name;
            this.url=url;
        }
    
    
        //2.重写call方法
    
        @Override
        public Boolean call() throws Exception {
            WebDownloader webDownloader = new WebDownloader();
            webDownloader.download(url,name);
            System.out.println("download name:"+name);
            return true;
        }
    
    
    
        //主线程main
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            TestThread05 t1 = new TestThread05("https://hao1.qhimg.com/t01ea3a44e231e5d6f4.png","1.png");
            TestThread05 t2 = new TestThread05("https://mvnrepository.com/img/1db2323c3992372f3dc1a4729ff507c5","2.png");
            TestThread05 t3 = new TestThread05("https://p1.ssl.qhimg.com/dr/270_500_/t019c311710c700e6dd.jpg?size=800x450","3.png");
    
            //创建执行服务
            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();
    
        }
    }
    
    
    //2.创建下载器
    class WebDownloader{
    
        //下载方法
        public void download(String url,String name){
            try{
                //FileUtils工具类 url 网站   file文件名
                FileUtils.copyURLToFile(new URL(url),new File(name));
            }catch (IOException e){
                e.printStackTrace();
                System.out.println("downloader方法出现问题");
            }
        }
    }
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值