一说到死锁,大家都有一种认识,死锁嘛,就是一种相互等待,想要争抢资源,可惜都不让步,导致程序运行不下去了的情况。线程死锁总感觉了解一些,但真让自己说明白点的时候,又不知道从那说了,有时候面试官还会让你写一个死锁,写死锁你肯定明白,只是贸然去写好像又不知道从哪里开始,今天我们就来写一个死锁,让程序死机,哈哈
1.使用Synchronized实现
package com.example.demoproject;
public class DeadThread implements Runnable{
private Object lock1 = new Object() ;
private Object lock2 = new Object() ;
public void method() throws Exception{
System.out.println("死锁开始~~~");
synchronized (lock1){
System.out.println(Thread.currentThread().getName()+":锁住了lock1");
Thread.sleep(1000);
synchronized (lock2){
System.out.println(Thread.currentThread().getName()+":锁住了lock2");
}
}
}
public void otherMethod() throws Exception{
System.out.println();
synchronized (lock2){
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+":锁住了lock2");
synchronized (lock1){
System.out.println(Thread.currentThread().getName()+":锁住了lock1");
}
}
}
@Override
public void run() {
try {
method();
otherMethod();
} catch (Exception e) {
}
}
public static void main(String[] args) {
DeadThread deadThread = new DeadThread();
new Thread(deadThread,"线程A").start();
new Thread(deadThread,"线程B").start();
}
}
方法method先锁lock1,再锁lock2,当然中间等待了,等待otherMethod 去锁lock2,不然method执行完了,otherMethod再去加锁也发生不了死锁。这里的睡眠等待就是模拟高并发情况下线程抢占资源时可能发生的情况。
细看一下,其实这个写的并不怎么样,method(),otherMethod()分别使用一个线程启动,也就能发生死锁了,我这个为了少写一个Thread或者说是少写一个Runnable,直接把他们放在了一个run方法下,其实是有点多余的。下面我们直接使用最省事的方式写一个死锁,当然是代码省事,不是锁省事,实现一个死锁肯定还是synchronized最方便,不用去解锁操作。
2.使用ReentrantLock加锁
public class DeadThreadLock {
private static Lock lock1 = new ReentrantLock() ;
private static Lock lock2 = new ReentrantLock() ;
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
try {
lock1.lock();
System.out.println(Thread.currentThread().getName()+"lock1加锁成功");
Thread.sleep(1000);
lock2.lock();
System.out.println(Thread.currentThread().getName()+"lock1,2加锁成功");
lock1.unlock();
lock2.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"线程A").start();
new Thread(new Runnable() {
@Override
public void run() {
try {
lock2.lock();
System.out.println(Thread.currentThread().getName()+"lock2加锁成功");
Thread.sleep(1000);
lock1.lock();
System.out.println(Thread.currentThread().getName()+"lock1,2加锁成功");
lock1.unlock();
lock2.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"线程B").start();
}
}
代码很平淡,就是两个锁竞争,线程A占有了 lock1,线程B占有了lock2,然后 线程B在lock1的阻塞队列里等待线程A释放lock1,线程A在lock2 的阻塞队列里等待线程B释放lock2,望眼欲穿啊,可惜,然并卵,哎呀,卡着了,老尴尬了,哈哈。 大家有兴趣可以自己写下试试哈,方式有很多,解决死锁不容易,创建死锁还不简单?哈哈,咱们都是能创造问题的人!!
No sacrifice,no victory~