死锁
产生死锁的四个必要条件:
1.互斥条件:一个资源每次只能被一个进程使用
2.请求与保持条件:一个进程因请求资源而被阻塞时,对已获得的资源保持不放
3.不剥夺条件:进程已获得的资源,在未使用完之前不能强行剥夺
4.循环等待条件:若干进程间形成一种头尾相接的循环等待资源关系
(破除一个条件即可解除死锁)
//死锁:多个线程互相抱着对方需要的资源,如何形成僵持
public class DeadLock {
public static void main(String[] args) {
MakeUp g1 = new MakeUp(0,"小红");
MakeUp g2 = new MakeUp(1,"小花");
g1.start();
g2.start();
}
}
//
class MakeUp extends Thread{
//需要的资源只有一份,用static来保证
static LipStick lipStick = new LipStick();
static Mirror mirror = new Mirror();
int choice ;//选择
String name;//使用化妆品的人
MakeUp(int choice, String name){
this.choice = choice;
this.name = name;
}
//化妆,互相持有对方的锁,拿着对方想要的资源
private void makeup() throws InterruptedException {
if (choice == 0){
synchronized (lipStick){//获得口红的锁
System.out.println(this.name + "获得了口红的锁");
Thread.sleep(1000);
synchronized (mirror){//获得镜子的锁
System.out.println(this.name + "获得了镜子的锁");
}
}
}else{
synchronized (mirror){//获得镜子的锁
System.out.println(this.name + "获得了镜子的锁");
Thread.sleep(2000);
synchronized (lipStick){//获得口红的锁
System.out.println(this.name + "获得了口红的锁");
}
}
}
}
@Override
public void run() {
try {
makeup();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//镜子
class Mirror{}
//口红
class LipStick{}
互相抱有对方资源,陷入死锁状态:
对同步块里的代码进行修改,将同步块里的锁移出同步块,表示执行完同步块,释放了锁再去获取另外一个锁,从而就不会发生死锁:
结果如下:
Lock锁
1.Lock锁是显示锁,而synchronized 是隐式锁,出了作用域就会释放。
2.Lock中只有代码块锁。synchronized 则有代码块锁和方法锁
3.用Lock锁,jvm花费较少的时间来调度线程,性能更好,并且有丰富的拓展类。
4.优先使用:Lock > 同步代码块(进入方法体,分配好相应资源)> 同步方法(方法体之外)
5.对象.Lock为加锁,对象.lock为释放锁
import java.util.concurrent.locks.ReentrantLock;
//测试Lock类
public class TestLock {
public static void main(String[] args) {
TestLock2 testLock2 = new TestLock2();
Thread t1 = new Thread(testLock2);
Thread t2 = new Thread(testLock2);
Thread t3 = new Thread(testLock2);
t1.start();
t2.start();
t3.start();
}
}
class TestLock2 implements Runnable{
int ticketnum = 10;
//定义lock锁
private final ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while(true){
try{
//解锁
lock.lock();
if(ticketnum > 0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(ticketnum--);
}else{
break;
}
}finally {
//解锁,记得要写在finally代码块里面
lock.unlock();
}
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/84198.html