java线程安全问题--"卖票问题"

当java程序启动至少有几个线程产生?

当java程序从main方法开始执行时,就会伴随着一个线程的产生,程序结束后也会伴随着线程回收机制的开启,也会有有一个线程产生。所以在java程序开始执行时,至少有两个线程。

程序的设计是这样的:模拟电影院卖票问题,假如一家电影院正在上映唐人街探案6,假设一个电影院只有100张票,分四个窗口来售票。接下来我把代码和问题展示给大家。

在这里插入图片描述
在这里插入图片描述
我们期望的是运行结果应该是:当100张票卖完时,就停止售票,但是执行结果和我们想的可能有点不同
在这里插入图片描述
这就是我们所说的线程安全问题,在这里我想给大家说的是,线程安全问题都是由全局变量和静态变量引起的,如果每个线程对全局变量和静态变量只有读操作,没有写操作,一般来讲这个线程是安全的。但是多个线程同时执行写操作的话,此时的线程是不安全的,一般来说可以用同步代码块来解决此问题(synchronized)

解决这个问题的原理:同步代码块(synchronized)介意存在某个方法的区块中,互斥访问,在上里面加上同步锁(lock),就表示当线程分配到一窗口执行卖票时,其他窗口不能进行卖票,在外面等着,当线程分配到窗口三卖票时,其他窗口不能卖票

同步锁:任何时候都只能有一线程拿到同步锁,谁拿到同步锁谁就可以进入到同步代码块中。
在这里插入图片描述
此时我们看到的结果就和我们预期想的一样了,因此也就解决了线程安全问题。
在这里插入图片描述

同步方法:

在这里给大家扩展一下什么是同步方法:用synchronized修饰的方法称为同步方法:,保证A线程执行该方法的时候,其他线程只能在方法外 等着。
格式是这样的:
public synchronized void method(){
可能会产生线程安全问题的代码
}
同步代码块的锁对象是同步锁(lock),那么同步方法的锁对象是谁呢
同步方法的锁对象是分情况的:

  1. 对于非静态方法,同步锁是this
  2. 对于static方法,同步锁是字节码对象即:类名.class

接下来给大家演示一下关于使用同步方法来实现对售票线程安全的问题:

在这里插入图片描述
执行结果也是没有问题的:
在这里插入图片描述

发布了16 篇原创文章 · 获赞 20 · 访问量 290

猜你喜欢

转载自blog.csdn.net/duanyaowei/article/details/105605542