java线程中的死锁,java多线程中的死锁情况

当两个线程相互等待对方释放同步监视器时就会发生死锁,Java虚拟机没有监测,也没有采取措施来处理死锁情况,所以多线程编程时应该采取措施避免死锁出现。一旦出现死锁,整个程序既不会发生任何异常,也不会给出任何提示,只是所有线程处于阻塞状态,无法继续。

class A {

public synchronized void foo(B b) {

System.out.println("当前线程名:" + Thread.currentThread().getName() + " 进入 A 实例的 foo() 方法");

try {

Thread.sleep(200);

} catch (InterruptedException ex) {

ex.printStackTrace();

}

System.out.println("当前线程名:" + Thread.currentThread().getName() + " 企图调用 B 实例的 last() 方法");

b.last();

}

public synchronized void last() {

System.out.println("进入了 A 类的 last() 方法内部");

}

}

class B {

public synchronized void bar(A a) {

System.out.println("当前线程名:" + Thread.currentThread().getName() + " 进入了B实例的bar()方法");

try {

Thread.sleep(200);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("当前线程名 " + Thread.currentThread().getName() + " 企图调用A实例的 last() 方法");

a.last();

}

public synchronized void last() {

System.out.println("进入了 B 类的 last() 方法内部");

}

}

public class DeadLock implements Runnable {

A a = new A();

B b = new B();

public void init() {

Thread.currentThread().setName("主线程");

a.foo(b);

System.out.println("进入了主线程之后");

}

@Override

public void run() {

Thread.currentThread().setName("副线程");

b.bar(a);

System.out.println("进入了副线程之后");

}

public static void main(String[] args) {

DeadLock dl = new DeadLock();

new Thread(dl).start();

dl.init();

}

}

000006e7855e39183d7adbdeed0c97a7.png

避免死锁的常见方式:

避免多次锁定:尽量避免同一个线程对多个同步监视器进行锁定。比如上面的死锁程序,主线程要对A、B两个对象(同步监视器)进行锁定,副线程也要对A、B两个对象进行锁定,这就埋下了导致死锁的隐患。

具有相同的加锁顺序:如果多个线程需要对多个同步监视器进行锁定,则应该保证它们以相同的顺序请求加锁。比如上面的死锁程序,主线程先对A对象(同步监视器)加锁,再对B对象(同步监视器)加锁;而副线程则先对B对象加锁,再对A对象加锁。这种方式很容易形成嵌套锁定,进而导致死锁。如果让主线程、副线程按相同的顺序加锁,就可以避免死锁问题。

使用定时锁:程序调用Lock对象的tryLock()方法加锁时可指定time和unit参数,当超过指定时间后会自动释放对Lock的锁定,这样就可以解开死锁了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值