Java-多线程之安全问题讨论

一.需求:某电影院目前正在上映贺岁大片,共有100张票,而它有3个售票窗口售票,请设计一个程序模拟该电影院售票。
案例1
在这里插入图片描述
在这里插入图片描述
可以看出,三个窗口自己卖自己的100张票,显然是不符合需求的,所以需要作出改进,让票数让三个线程对象共享,就把票数设置为静态的(static)
-----案例2改进
在这里插入图片描述
在这里插入图片描述
现在虽然解决了总共卖100张票的问题,但又了新的问题,出售票数顺序出现了混乱,这显然是不符合需求的,在真实环境中,售票时网络是不能实时传输的,总是存在延迟的情况,所以,在出售一张票以后,需要一点时间的延迟
案例3改进
在这里插入图片描述
在这里插入图片描述
二.线程安全问题的产生原因分析
(一)为什么出现安全问题?(也是我们判断是否有问题的标准)
是否是多线程环境
是否有共享数据
是否有多条语句操作共享数据
(二)如何解决多线程安全问题呢?
基本思想:让程序没有安全问题的环境。
怎么实现呢?
把多个语句操作共享数据的代码给锁起来,让任意时刻只能有一个线程执行即可。需要使用同步代码块
(三)同步代码块
这个同步代码块保证数据的安全性的一个主要因素就是这个对象 注意这个对象 要定义为静态成员变量 才能被所有线程共享
需要这个对象被所有的线程对象所共享
这个对象其实就是一把锁.
这个对象习惯叫做监视器
格式:

  • synchronized(对象){//不能在括号了直接new 对象 new 了 就没效果
    要被同步的代码 ;
    }
    案例在这里插入图片描述
    同步代码块的锁对象: 任意一个对象

(四).同步方法
在这里插入图片描述
可以把需要操作共享数据的代码整合到一个方法里面,这个方法称为同步方法,需要用synchronized修饰
同步方法的锁对象: 是this
静态同步方法的锁对象:就是当前类对应的字节码文件对象MyRunable.class
三.加锁的其他方式(JDK5之后的Lock锁的概述和使用)
(一)Lock锁的概述
虽然我们可以理解同步代码块和同步方法的锁对象问题,
但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,
为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象
(二)Lock和ReentrantLock
void lock()//加锁
void unlock()//释放锁
(三)案例演示(lock锁的使用)
在这里插入图片描述
(四)死锁问题
-----死锁概述
如果出现了同步嵌套,就容易产生死锁问题
是指两个或者两个以上的线程在执行的过程中,因争夺资源产生的一种互相等待现象
------死锁问题演示
在这里插入图片描述
设计程序应该尽量避免这种情况

猜你喜欢

转载自blog.csdn.net/PreyHard/article/details/84038159