在练习Java多线程的过程中,通常都会通过多窗口卖票这个问题来详细逐渐解析多线程的线程同步,其中涉及到同步代码块
,同步方法
和互斥锁
。
铁道部发布了一个售票任务,销售1000张票,要求有10个窗口来进行销售,请编写多线程程序来模拟这个效果。
1 第一步
1 | class Test4Thread extends Thread { |
运行代码发现存量重复卖票问题,因为多个线程同时运行时,就会出现多个线程获取到的变量值是相同的,导致出现重复卖票问题。
2 第二步
1 |
|
这里虽然在循环体内部增加了同步代码块,但是可能在票数为1时,可能会出现多个线程进入循环体排队运行代码块的情况,这样就会出现买负数票的问题。
3 第三步
1 | public void run() { |
线程类的run方法经过修改后代码结果符合预期。
4 最终代码:
1 | class Test4Thread extends Thread { |
5 利用同步方法来处理卖票问题:
在Java
除了利用同步代码块之外,还可以利用同步方法来处理问题,利用同步方法时仍要要注意调用同步方法是他一个对象,所以继承的线程类需要增加static
关键字,同样需要通过同步方法的返回值来判断线程票是否卖完。
1 | class Test5Thread extends Thread { |
6 利用互斥锁来解决卖票问题:
除了利用同步代码块和同步方法外,在Java
里面还可以利用互斥锁来处理,在用互斥锁处理的过程中,为了避免出现死锁问题,需要利用try-finally
来互斥锁,将结果代码放在finally
代码块中。
1 | import java.util.concurrent.locks.Lock; |