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

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


相关文章

Java多线程汇总:Java多线程


一、线程调度顺序

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

  • 代码实现案例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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) 线程休眠,参数单位是毫秒
  • 代码实现案例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
java复制代码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人!
+ 手机,是肯定不够滴~
+ 我们来模拟一下抢购手机的场景
  • 代码实现案例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
java复制代码/**
* 手机抢购案例
*/
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

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%