线程创建的三种方法

继承Thread类

//1.继承Thread类  2.重写run()方法  3.调用start()方法开启线程
public class testThread1 extends Thread{
    @Override
    public void run() {
        //run 方法流程体
        for (int i = 0; i < 10; i++) {
            System.out.println("====================");
        }
    }

    public static void main(String[] args) {//main 线程,主线程
        //start 方法开启线程
        testThread1 testThread1 = new testThread1();
        testThread1.start();

        for (int i = 0; i < 1000; i++) {
            System.out.println("----------------------------------");

        }
    }
}

分析:当多线程没有开启时,代码只执行主线程里面的main里面的代码,当开启后,线程开启后不一定立即执行,根据CPU调度

运行结果:
Thread类

实现runnable接口

  1. 实现runnable接口
  2. 重写run方法
  3. 创建线程,用线程实现start 方法
  4. 一般建议使用runnable接口
//创建线程,实现 runnable接口,重写run 方法,执行线程需要丢入runnable接口实现类
public class testThread3 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 200; i++) {
            System.out.println("我在看代码"+i);

        }
    }

    public static void main(String[] args) {
        //创建runnable接口的实现对象
        testThread3 testThread3 = new testThread3();
        //创建线程对象,通过线程对象来开启我们的线程,相当于代理
        //Thread thread = new Thread(testThread3);
        //thread.start();这两句和 new Thread(testThread3).start();意思相同
        new Thread(testThread3).start();
        for (int i = 0; i < 100; i++) {
            System.out.println("shmily"+i);
        }
    }
}

与thread不同之处是:

  1. Thread直接new一个类,用这个类直接开启这个线程
  2. runnable使用new一个这个类,在new一下Thread,之后在start,一般建议用Runnable方法

案例:网图下载

  1. 下载类,类里面写方法包括地址和名字
  2. 继承Thread类,构造器写地址和名字
  3. 重写run方法,run方法里面写下载类里面的东西
  4. 在主函数里面用start的方法开启线程
    举例:
//练习Thread,实现多线程图片下载器
public class testThread2 extends Thread{
    private String url;//网络图片的地址
    private String name;//保存的文件名

    //构造器
    public testThread2(String url,String name){
        this.url=url;
        this.name=name;
    }
    @Override
    public void run() {
        WebDownLoader webDownLoader = new WebDownLoader();
        webDownLoader.downLoader(url,name);
        System.out.println("下载了的文件名:"+name  );
    }

    public static void main(String[] args) {
        testThread2 thread2 = new testThread2("https://csdnimg.cn/feed/20200423/bb8e24713d67af32f82c5a4ffacd043f.jpg","2.jpg");
        thread2.start();
    }
}
//下载器
class WebDownLoader {
    //下载方法
    public void downLoader(String url,String name )  {
        try {
            FileUtils.copyURLToFile(new URL(url),new File(name));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行结果:
网图下载

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

1.多个线程操作同一个线程对象,会出现紊乱现象,一个票可能会出现多个人拿到,由于票数较少,所以添加了时间延时功能,
2.Thread.currentThread().getName()拿到名字

//多个线程同时操作同一个对象
//买火车票的例子

public class testThread4 implements Runnable{
    private int ticketNums=10;

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

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

运行结果为:
多线程

龟兔赛跑例子

  1. 首先来个赛道距离,然后要离终点越来越近
  2. 判断比赛是否结束
  3. 打印出胜利者
  4. 龟兔赛跑开始
  5. 故事中是乌龟赢了,兔子需要睡觉,所以我们来模拟兔子睡觉
  6. 终于,乌龟赢得比赛
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("兔子") && i%10==0){
                try {
                    Thread.sleep(5);
                } 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();
    }
}

运行结果:
Race
Race2

实现Callable接口

  1. 实现callable接口,需要返回值类型
  2. 重写call方法,需要抛出异常
  3. 创建目标对象
  4. 创建执行服务: ExecutorService ser=Executors.newFixedThreadPool(1);
  5. 提交执行: Future result1 = ser.submit(t1);
  6. 获取结果: boolean r1 = result1 .get()
  7. 关闭服务: ser.shutdownNow();
//callable中的返回值类型和call方法中的返回值保持一致
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://csdnimg.cn/feed/20200423/bb8e24713d67af32f82c5a4ffacd043f.jpg","2.jpg");
        testCallable t2 = new testCallable("https://csdnimg.cn/feed/20200423/bb8e24713d67af32f82c5a4ffacd043f.jpg","1.jpg");


        //创建执行服务:后边的数字表示有几个线程就是几
        ExecutorService ser = Executors.newFixedThreadPool(2);
        //提交执行:
        Future<Boolean> r1 = ser.submit(t1);
        Future<Boolean> r2 = ser.submit(t2);
       // 获取结果:
        boolean rs1 = r1.get();
        boolean rs2 = r2.get();
        System.out.println(rs1);
        System.out.println(rs2);

        //关闭服务:
        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();
        }
    }
}

线程创建的三种方式:Thread类,Runnable接口和Callable接口

  • 2
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值