模擬死鎖:
/**
* Create by LiXiaoTian 2020/5/10 11:34
* 死鎖問題
*/
public class Deadlock {
public static String resource1 = "resource1";
public static String resource2 = "resource2";
public static void main(String[] args) {
Thread thread1 = new Thread(new BusinessA());
Thread thread2 = new Thread(new BusinessB());
thread1.setName("線程1");
thread2.setName("線程2");
thread1.start();
thread2.start();
}
static class BusinessA implements Runnable {
@Override
public void run() {
try{
System.out.println("BusinessA啓動");
while(true){
synchronized(Deadlock.resource1){
System.out.println("BusinessA拿到了resource1的鎖");
Thread.sleep(3000);//獲取resource1後先等一會兒,讓BusinessB有足夠的時間鎖住resource2
System.out.println("BusinessA想拿resource2的鎖。。。。");
synchronized(Deadlock.resource2){
System.out.println("BusinessA獲得到了resource2的鎖");
}
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
static class BusinessB implements Runnable {
@Override
public void run(){
try{
System.out.println("BusinessB啓動");
while(true){
synchronized(Deadlock.resource2){
System.out.println("BusinessB拿得到了resource2的鎖");
Thread.sleep(3000);//獲取resource2後先等一會兒,讓BusinessA有足夠的時間鎖住resource1
System.out.println("BusinessB想拿resource1的鎖。。。。");
synchronized(Deadlock.resource1){
System.out.println("BusinessB獲得到了resource1的鎖");
}
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
}
如何解決死鎖呢?
解決方法:
1、線程因某個條件爲未滿足而受阻,不能讓其繼續佔有資源,也就是說,讓進入阻塞狀態的線程釋放所有資源。
2、如果有多個對象需要互斥訪問,應該確定線程獲得鎖的順序,並保證整個程序以相反的順序釋放鎖。也就是說,一個線程獲得一個資源的鎖之後,不能再佔用其他對象資源的鎖,釋放資源鎖的順序:先被佔有的資源的鎖後釋放。
/**
* Create by LiXiaoTian 2020/5/10 11:34
* 解決死鎖問題
*/
public class Deadlock {
public static ReentrantLock lock1 = new ReentrantLock();
public static ReentrantLock lock2 = new ReentrantLock();
public static String resource1 = "resource1";
public static String resource2 = "resource2";
public static void main(String[] args) {
Thread thread1 = new Thread(new BusinessA());
Thread thread2 = new Thread(new BusinessB());
thread1.setName("線程1");
thread2.setName("線程2");
thread1.start();
thread2.start();
}
static class BusinessA implements Runnable {
boolean flag = true;
@Override
public void run() {
try {
System.out.println("線程1啓動");
while (flag) {
Thread.sleep(1000);
if (Deadlock.lock1.tryLock(1, TimeUnit.SECONDS)) {
System.out.println("線程1已鎖住lock1");
Thread.sleep(5000);
if (Deadlock.lock2.tryLock(1, TimeUnit.SECONDS)) {
System.out.println("線程1已鎖住lock2");
flag = false;
} else {
System.out.println("線程1鎖失敗lock2");
}
} else {
System.out.println("線程1鎖失敗lock1");
}
System.out.println("當前線程===========================" + Thread.currentThread().getName());
//釋放鎖
if (lock1.isHeldByCurrentThread()) {
lock1.unlock();
System.out.println("線程1釋放lock1");
}
if (lock2.isHeldByCurrentThread()) {
lock2.unlock();
System.out.println("線程1釋放lock2");
}
Thread.sleep(2000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
static class BusinessB implements Runnable {
boolean flag = true;
@Override
public void run() {
try {
System.out.println("線程2啓動");
while (flag) {
if (Deadlock.lock1.tryLock(1, TimeUnit.SECONDS)) {
System.out.println("線程2已鎖住lock1");
Thread.sleep(6000);
if (Deadlock.lock2.tryLock(1, TimeUnit.SECONDS)) {
System.out.println("線程2已鎖住lock2");
flag = false;
} else {
System.out.println("線程2鎖失敗lock2");
}
} else {
System.out.println("線程2鎖失敗lock1");
}
System.out.println("當前線程===========================" + Thread.currentThread().getName());
//釋放鎖
if (lock1.isHeldByCurrentThread()) {
lock1.unlock();
System.out.println("線程2釋放lock1");
}
if (lock2.isHeldByCurrentThread()) {
lock2.unlock();
System.out.println("線程2釋放lock2");
}
}
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}