线程的调度顺序和线程的并发 | Java多线程(二)

1,591 阅读2分钟

这是我参与更文挑战的第26天,活动详情查看: 更文挑战


相关文章

Java多线程汇总:Java多线程


一、线程调度顺序

前提: 如果一个进程中同时开三个线程,那么谁先谁后呢?

  • 代码实现案例:
/**
 * 测试线程的执行顺序
 */
public class TestThreadSort implements Runnable{
    public static void main(String[] args) {
        //使用实现Runnable方法的好处就是可以多实现
        TestThreadSort testThreadSort = new TestThreadSort();

        //开启线程1
        new Thread(testThreadSort,"丁大大").start();
        //开启线程2
        new Thread(testThreadSort,"甲大大").start();
        //开启线程3
        new Thread(testThreadSort,"乙大大").start();
    }

    @Override
    public void run() {
        //Thread.currentThread().getName() ---获取当前线程的名称
        for (int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+"看了第"+i+"本书");
        }
    }
}
  • 执行结果如下:

在这里插入图片描述

  • 注意项:

    • 开启一个线程时,即new Thread(实例化对象,name),为开启的线程取了一个名字
    • 在线程内部可使用Thread.currentThread().getName() 获取该线程本身的名称。
  • 小结:

    • 通过以上的代码执行结果来看,我们可以得出结论,线程的执行并不是按照指定的顺序来,比如我依次开启线程1、2、3,但实际的执行结果并不受我们的控制,而是由cpu调度器随机调度执行的!

二、主线程的执行

  • 代码实现案例

在这里插入图片描述

  • 理论上结果:等待三个人看完,最后才是老师看书。

  • 实际结果如下:

在这里插入图片描述

  • 结论:主线程(main()线程)优先执行。

三、线程的并发

并发,在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。 ----以上摘自百度百科

3.1、龟兔赛跑案例

  • 在开始并发之前,我们先来看一个好玩的案例。龟兔赛跑

  • 程序实现

    • 赛道两条
    • 乌龟和兔子
    • 赛道长度
    • 根据历史来看,需要让兔子间隔休息(因为最后兔子输了嘛)
    • sleep(int) 线程休眠,参数单位是毫秒
  • 代码实现案例:

public class RunGame implements Runnable{

    Integer track = 100;//赛道的长度
    String turtle = "乌龟";
    String rabbit = "兔子";
    String winner = "";//胜利者

    public static void main(String[] args) {
        RunGame runGame = new RunGame();

        //开启兔子比赛的线程
        new Thread(runGame, runGame.rabbit).start();
        //开启乌龟比赛的线程
        new Thread(runGame, runGame.turtle).start();
    }

    @Override
    public void run() {
        //使用Thread.currentThread().getName()获得当前的参赛者是谁
        String ballplayer = Thread.currentThread().getName();
        if (ballplayer.equals(rabbit)){
            //模拟兔子跑步的速度,兔子跑的快,定义为每秒跑两米
            for (int i=0;i<=track;i+=2){
                System.out.println(rabbit+"跑了"+i+"米");
                //因为兔子比较骄傲,当兔子跑到60米时,睡了一会觉,导致输掉比赛
                if (i==50){
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                if (i>=100){
                    winner = rabbit;
                    System.out.println(winner+"赢了!!!");
                }
            }
        }else if (ballplayer.equals(turtle)){
            //模拟乌龟跑步的速度,乌龟跑的慢,定义为每秒跑一米
            for (int i=0;i<=track;i++){
                System.out.println(turtle+"跑了"+i+"米");
                if (i>=100){
                    winner = turtle;
                    System.out.println(winner+"赢了!!!");
                }
            }
        }
    }
}

  • 执行结果:

在这里插入图片描述

  • 当兔子跑到50米时骄傲自满,睡了觉,导致比赛输掉。

在这里插入图片描述

  • 正常情况下,兔子肯定会赢,去掉休眠即可,我就不放代码和结果上来了,感兴趣的可以自己试试~

3.2、商品抢购案例

  • 并发的场景:

    • 刷猴王雷军发售小米12,首批货源只有100台!!!100台啊!!!
    • 大家知道消息后,纷纷跑来在12点首发时抢购小米12,人数共有500人!
    • 手机,是肯定不够滴~
    • 我们来模拟一下抢购手机的场景
  • 代码实现案例:

/**
 * 手机抢购案例
 */
public class PhoneSnapUp implements Runnable{

    private Integer inventory = 100;//手机库存
    private Integer number = 500;//抢购人数

    public static void main(String[] args) {
        PhoneSnapUp phoneSnapUp = new PhoneSnapUp();
        //模拟500人同时抢购,即同时开启500个线程
        for (int i=0;i<500;i++){
            new Thread(phoneSnapUp,"丁大大"+i+"一号").start();
        }
    }

    @Override
    public void run() {
        //写个死循环来模拟
        while (true){
            //当库存为0时,抢购结束
            if (inventory <= 0){
                break;
            }
            //模拟延迟,否则结果不容易看出来
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("恭喜!!"+Thread.currentThread().getName()+"--抢到了一台小米12!库存还剩:"+inventory+"台");
            //每次抢购完,库存减1
            inventory--;
        }
    }
}
  • 执行结果如下:

在这里插入图片描述

在这里插入图片描述

  • 结论:出现的问题

    • 同一台手机被多人购买
    • 卖出的手机远超库存量
  • 通过上面的案例,可以让我们对并发有个大概的了解!这也是我们在实际开发中需要注意的东西!


路漫漫其修远兮,吾必将上下求索~

如果你认为i博主写的不错!写作不易,请点赞、关注、评论给博主一个鼓励吧~hahah