这是我参与8月更文挑战的第21天,活动详情查看:8月更文挑战
前言
synchronized(同步锁)关键字的作用就是利用特定的对象设置一个锁lock,在多线程并发访问时,同时只允许一个线程可以获得这个锁,执行特定的代码。执行后释放锁,继续由其它线程争抢。
Synchronize的使用场景
可以使用在以下三种场景,对应不同的锁对象
- synchronize代码块:任意对象即可
synchronize(object){}- synchronize方法:this当前对象
synchronize(this){}- synchronize静态方法:当前类的字节码对象
synchronize(Object.calss){}
线程的五种状态
- 1. 新建(new)
- 2. 就绪(ready)
- 3. 运行中(running)
- 4. 阻塞(blocked)
- 5. 死亡(dead)
死锁的产生
死锁是多线程情况下最严重的问题,出现死锁的原因是,多个线程对公共资源进行操作时,彼此不释放自己占有的资源,而去试图操作其它线程的资源,从而形成了交叉引用,就会产生死锁
例子
线程A任务是向
A和B两个文件写入信息,操作步骤:先获取文件A,写入,再获取文件B,写入,然后释放文件A和文件B
线程B任务也是是向B和A两个文件写入信息,操作步骤:先获取文件B,写入,再获取文件A,写入,然后释放文件A和文件B
注意:这里区别是一个先写文件A,一个先写文件B
这里就出现了公共资源交叉引用的问题,当两个线程同时执行
- 线程A占有了
文件A,这个时候线程B占有了文件B;- 线程A在
文件A中写入信息后想去获取文件B,但是文件B被线程B占用着,这个时候线程A占用着文件A,等待线程B释放文件B,但是反过来,线程B占用着文件B,等待着线程A释放文件A,这时候双方都持有对方需要的资源,但是又不释放自己当前占有的,互相等待,出现了死锁的情况。
解决死锁的建议
- 尽量减少公共资源的引用,用完马上释放
- 减少synchronize使用,采用“副本”方式替代