忘掉Java多线程,我们来看看现实生活中的例子
由卖票引发的思考
热门景区往往会开设多个售票窗口,一是为了同时接待更大的客流量,而是为了防止一个售票窗口机器出现故障导致所有人都买不了票。这里引出多线程中最重要的概念之一,阻塞。
实际上,在单核中运行多线程不一定比单线程要快,因为cpu需要调度和切换线程,那我们会什么要使用多线程?实际上使用多线程技术的一个重要原因就是——防止单个线程可能出现阻塞,导致整个工程无法向下继续运行。回顾一下你们自己项目使用多线程的场景,是不是也是因为有可能出现组塞的情况才使用多线程呢?如果不存在线程可能会阻塞的情况,那么是完全没有必要使用多线程的,这便是使用多线程的一个非常重要的前提——阻塞。下面我们用代码来模拟一下单窗口和多窗口售票的情景:
//只有一个窗口售票
public class SimpleStation {private static int ticks = 20;
public static void main(String[] args) {
while (ticks > 0) {
if (ticks == 15) {
// 这里模拟售票机器故障
throw new RuntimeException("machine down...");
}
ticks --;
System.out.println("卖了一张票,还剩下:" + ticks + "张票");
}
}
}
【忘掉Java多线程,我们来看看现实生活中的例子】运行结果:
卖了一张票,还剩下:19张票
卖了一张票,还剩下:18张票
卖了一张票,还剩下:17张票
卖了一张票,还剩下:16张票
卖了一张票,还剩下:15张票
Exception in thread "main" java.lang.RuntimeException: machine down...
at SimpleStation.main(SimpleStation.java:9)Process finished with exit code 1
从上面运行结果我们可以看到在余票还有15张票的时候,由于唯一售票的机器发生故障之后,剩余15张票就卖不出去了。接下来我们用多线程来解决这个问题:
public class Station extends Thread {static int ticks = 20;
static Object obj = "LOCK";
public Station(String name) {
super(name);
}@Override
public void run() {
while (ticks > 0) {
System.out.println(getName() + "卖票中");
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (totalTick > 15 && getName().equals("window1")) {
// 这里模拟窗口1的售票机器发生故障
throw new RuntimeException(getName() + "发生故障了");
}
synchronized (obj) {
if (totalTick > 0) {
// 这里totalTick为受限共享资源
totalTick--;
System.out.println(getName() + "票卖了1张,还剩:" + totalTick + "张票");
} else {
System.out.println(getName() + "今天的票卖完了");
}
}
}
}
}
运行结果:
window2卖票中
window3卖票中
window1卖票中
window3票卖了1张,还剩:19张票
window3卖票中
window2票卖了1张,还剩:18张票
window2卖票中
Exception in thread "window1" java.lang.RuntimeException: window1发生故障了
at Station.run(MainClass.java:21)
window3票卖了1张,还剩:17张票
window3卖票中
window2票卖了1张,还剩:16张票
window2卖票中
window3票卖了1张,还剩:15张票
window3卖票中
window2票卖了1张,还剩:14张票
window2卖票中
window3票卖了1张,还剩:13张票
window3卖票中
window2票卖了1张,还剩:12张票
window2卖票中
window3票卖了1张,还剩:11张票
window3卖票中
window2票卖了1张,还剩:10张票
window2卖票中
window3票卖了1张,还剩:9张票
window3卖票中
window2票卖了1张,还剩:8张票
window2卖票中
window3票卖了1张,还剩:7张票
window3卖票中
window2票卖了1张,还剩:6张票
window2卖票中
window3票卖了1张,还剩:5张票
window3卖票中
window2票卖了1张,还剩:4张票
window2卖票中
window3票卖了1张,还剩:3张票
window3卖票中
window2票卖了1张,还剩:2张票
window2卖票中
window3票卖了1张,还剩:1张票
window3卖票中
window2票卖了1张,还剩:0张票
window3今天的票卖完了
我们可以看到,虽然窗口1的机器发生故障了,但是并不影响窗口2和窗口3继续将票卖完。这就是多线程的魅力!
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 放屁有这三个特征的,请注意啦!这说明你的身体毒素太多
- 爱就是希望你好好活着
- 昨夜小楼听风
- 知识
- 死结。
- 我从来不做坏事
- 烦恼和幸福
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- 事件代理