Java-多线程(死锁)
多个线程各种占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致两个或多个线程都在等待对方释放资源,都停止执行的情形,某一个同步块同时拥有"两个以上对象的锁"时,就可能会发生"死锁"的问题
模拟死锁
//测试死锁
//多个线程互相抱着对方的资源,形成僵持
public class DeadLock {
public static void main(String[] args) {
EatFood man1 = new EatFood(0,"小明");
EatFood man2 = new EatFood(1,"小红");
man1.start();
man2.start();
}
}
//食物
class Food{
}
//餐具
class Tableware{
}
class EatFood extends Thread{
//需要的资源只有一份,用static 保证只有一份
static Food food = new Food();
static Tableware tableware = new Tableware();
int choice;//选择,先拿食物还是先拿餐具
String man;//想吃食物的人
EatFood(int choice,String man){
this.choice = choice;
this.man = man;
}
@Override
public void run() {
//吃饭
Eat();
}
//拿到 food和tableware 两种资源才能吃饭
private void Eat(){
if (choice==0){
synchronized (food){//获得食物的锁
System.out.println(this.man+"获得食物的锁");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//一秒钟后想获得餐具
synchronized (tableware){
System.out.println(this.man+"获得餐具的锁");
}
}
}else {
synchronized (tableware){//获得餐具的锁
System.out.println(this.man+"获得餐具的锁");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//2秒钟后想获得食物
synchronized (food){
System.out.println(this.man+"获得食物的锁");
}
}
}
}
}
解决方案:
//拿到 food和tableware 两种资源才能吃饭
private void Eat(){
if (choice==0){
synchronized (food){//获得食物的锁
System.out.println(this.man+"获得食物的锁");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (tableware){//拿出来
System.out.println(this.man+"获得餐具的锁");
}
}else {
synchronized (tableware){//获得餐具的锁
System.out.println(this.man+"获得餐具的锁");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (food){
System.out.println(this.man+"获得食物的锁");
}
}
}
死锁的避免方法
破坏死锁产生的必要条件