死锁和Lock锁
死锁

//死锁:多个线程互相抱着对方需要的资源,然后形成僵持
public class DeadLock {
public static void main(String[] args) {
Makeup g1=new Makeup(0,"灰姑娘");
Makeup g2=new Makeup(1,"白雪公主");
g1.start();
g2.start();
}
}
//口红
class Lipstick{
}
//镜子
class Mirror{
}
class Makeup extends Thread{
//需要的资源只有一份,用static来保证只有一份
static Lipstick lipstick=new Lipstick();
static Mirror mirror=new Mirror();
int choice; //选择
String grilName; //使用化妆品的人
public Makeup(int choice, String grilName) {
this.choice = choice;
this.grilName = grilName;
}
@Override
public void run() {
//化妆
try {
makeup();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void makeup() throws InterruptedException {
if(choice==0){
synchronized(lipstick){ //获得口红锁
System.out.println(this.grilName+"获得口红的锁");
Thread.sleep(1000);
}
synchronized(mirror){
System.out.println(this.grilName+"获得镜子的锁");
}
}else {
synchronized(mirror){//获得镜子锁
System.out.println(this.grilName+"获得镜子的锁");
Thread.sleep(2000);
}
synchronized (lipstick){
System.out.println(this.grilName+"获得口红的锁");
}
}
}
}
死锁避免方法:
产生死锁的4个必要条件
1.互斥条件:一个资源每次只能被一个进程使用。(例子里如果都想拿口红镜子的话就会死锁)
2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。(例子里如:拿了镜子后不放还想拿口红)
3.不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。(例子里 如我拿着镜子你也不能抢)
4.循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。(你想要我的我想要你的)
以上列出了死锁的四个必要条件,我们只要想办法破其中的任意一个或多个条件就可以避免死锁方生。
Lock(锁)


import java.util.concurrent.locks.ReentrantLock; public class TestLock { public static void main(String[] args) { TestLock2 testLock2=new TestLock2(); new Thread(testLock2,"学生").start(); new Thread(testLock2,"老师").start(); new Thread(testLock2,"黄牛党").start(); } } class TestLock2 implements Runnable{ int ticketNums=10; ReentrantLock lock=new ReentrantLock(); @Override public void run() { while (true){ try { lock.lock(); //枷锁 if(ticketNums<1){ break; } else { System.out.println(Thread.currentThread().getName()+"拿到了第"+ticketNums--+"张票"); } }finally { lock.unlock(); //解锁 } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
两者对比
synchronized与lock的对比
1.Lock是显示锁(手动开启和关闭锁,别忘了关闭锁)synchronized是隐式锁,出了作用域自动释放。
2.Lock只有代码块锁,synchronized有代码块锁和方法锁。
3.使用Lock锁,JVM将花费较少的时间来调度线程,性能更好。并且具有更好的扩展性(提供更多的子类)
4.优先使用顺序:
Lock>同步代码块(已经进入了方法体,分配了相应资源)>同步方法(在方法体之外)

浙公网安备 33010602011771号