忘掉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继续将票卖完。这就是多线程的魅力!

    推荐阅读