一、簡介
多個線程各自佔有一些共享資源,並且互相等待其它線程佔有的資源才能進行,而導致的兩個或多個線程都在等待對方釋放資源,都停止執行的情景。某一個同步塊同時擁有“兩個以上對象的鎖”時,就可能會發生“死鎖”的問題。
主要點:
- 過多的同步可能造成相互不釋放資源。
- 從而互相等待,一般發生於同步中持有多個對象的鎖。
解決:不要在同一個代碼塊中,同時持有多個對象的鎖。
二、產生和解決死鎖問題
1、定義量
//口紅
class LipStick {
}
//鏡子
class Mirror {
}
2、定義化妝類,調用產生死鎖代碼
//化妝
class Markup extends Thread {
static LipStick lipStick = new LipStick();
static Mirror mirror = new Mirror();
//選擇
int choice;
// 名字
String girl;
public Markup(int choice, String girl) {
this.choice = choice;
this.girl = girl;
}
@Override
public void run() {
// 化妝
markup();
}
3、死鎖的產生位置
// 相互持有對方的對象鎖--》可能造成死鎖
private void markup() {
if (choice == 0) {
synchronized (lipStick) {//獲得口紅的鎖
System.out.println(this.girl + "塗口紅");
// 1秒後想擁有鏡子的鎖
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 產生死鎖
synchronized (lipStick){
System.out.println(this.girl+"塗口紅");
}
}
} else {
synchronized (mirror) {//獲得鏡子的鎖
System.out.println(this.girl + "照鏡子");
// 1秒後想擁有口紅的鎖
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 產生死鎖
synchronized (lipStick){
System.out.println(this.girl+"塗口紅");
}
}
}
}
4、死鎖的解決
將獲取鎖的代碼往外面移動一個,使先完成照鏡子的動作後,進入線程等待(等待獲取口紅的狀態)。
// 解決死鎖問題
synchronized (lipStick) {
System.out.println(this.girl + "塗口紅");
}
5、調用方法
public static void main(String[] args) {
Markup g1 = new Markup(1, "張柏芝");
Markup g2 = new Markup(0, "張柏芝");
g1.start();
g2.start();
}
三、完整代碼
public class DeadLock {
public static void main(String[] args) {
Markup g1 = new Markup(1, "張柏芝");
Markup g2 = new Markup(0, "張柏芝");
g1.start();
g2.start();
}
}
//口紅
class LipStick {
}
//鏡子
class Mirror {
}
//化妝
class Markup extends Thread {
static LipStick lipStick = new LipStick();
static Mirror mirror = new Mirror();
//選擇
int choice;
// 名字
String girl;
public Markup(int choice, String girl) {
this.choice = choice;
this.girl = girl;
}
@Override
public void run() {
// 化妝
markup();
}
// 相互持有對方的對象鎖--》可能造成死鎖
private void markup() {
if (choice == 0) {
synchronized (lipStick) {//獲得口紅的鎖
System.out.println(this.girl + "塗口紅");
// 1秒後想擁有鏡子的鎖
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 產生死鎖
/**
synchronized (lipStick){
System.out.println(this.girl+"塗口紅");
}
*/
}
// 解決死鎖問題
synchronized (lipStick) {
System.out.println(this.girl + "塗口紅");
}
} else {
synchronized (mirror) {//獲得鏡子的鎖
System.out.println(this.girl + "照鏡子");
// 1秒後想擁有口紅的鎖
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 產生死鎖
/**
synchronized (lipStick){
System.out.println(this.girl+"塗口紅");
}
*/
}
// 解決死鎖問題
synchronized (lipStick) {
System.out.println(this.girl + "塗口紅");
}
}
}
}