Java实现死锁

本文通过一个具体的Java示例,详细解析了多线程环境下如何产生死锁现象。两个线程分别获取不同对象的锁后,试图获取对方持有的锁,从而形成相互等待的状态,导致程序无法继续执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在多线程中,为了保证数据等准确性和一致性,一般在进行共享数据进行操作等时候,我们都会进行加锁,保证同一时间只有一个线程在操作这个对象。由于加锁的原因,如果一不注意的话很容易导致死锁。死锁的原因是两个线程或者多个线程在互相等待对方释放资源,一直在阻塞等待,这就造成了死锁。由于Java中没有对死锁进行监管的东西,在死锁中,线程会一直被阻塞,程序不会有任何提示的消息,也无法继续下去。

下面是一个死锁的例子,可以帮助大家理解死锁的机制:

package lock;

/**
 * Created by pozhen on 17/2/12.
 * 1.首先开启一个线程(副线程),启动线程后,会先进入run方法,run方法执行b.hold(a)方法,给b对象加了锁,然后休眠200ms
 * 2.然后主线程几乎是和副线程同时,但是会慢上一些进入init()方法,然后执行a.hold(b)方法,给a对象加了锁,然后休眠200ms
 * 3.b对象会提前结束休眠,将要执行代码4,需要给a对象加锁,但是现在a对象的锁被副线程持有,所以主线程阻塞,等待副线程释放a对象的锁。
 * 4.这时候副线程的休眠也结束了,将要执行代码2,需要给b加锁,但是现在b对象的锁被主线程持有,所以副线程阻塞,等待主线程释放b对象的锁。
 * 5.最后,主线程阻塞在等副线程释放锁,副线程也在阻塞等待主线程释放锁,这时候就一直等待下去,无穷无尽,这就造成了死锁。
 */
public class DeadLockExample implements Runnable{

    class A {
        public synchronized void hold(B b) {
            try {
                System.out.println(Thread.currentThread().getName()+"目前持有A的锁");//代码1
                Thread.sleep(200);
            }catch (Exception e) {
                e.printStackTrace();
            }
            b.last();
        }

        public synchronized void last() {
            System.out.println(Thread.currentThread().getName()+"的A对象企图访问B对象的last方法,准备要给B对象加锁");//代码2
        }
    }

    class B {
        public synchronized void hold(A a) {
            try {
                System.out.println(Thread.currentThread().getName()+"目前持有B的锁");//代码3
                Thread.sleep(200);
            }catch (Exception e) {
                e.printStackTrace();
            }
            a.last();
        }
        public synchronized void last() {
            System.out.println(Thread.currentThread().getName()+"的B对象企图访问A对象的last方法,准备要给A对象加锁");//代码4
        }
    }

    A a = new A();
    B b = new B();

    public void init() {
        Thread.currentThread().setName("主线程");
        a.hold(b);
    }

    @Override
    public void run() {
        Thread.currentThread().setName("副线程");
        b.hold(a);
    }

    public static void main(String[] args) {
        DeadLockExample deadLockExample = new DeadLockExample();
        new Thread(deadLockExample).start();
        deadLockExample.init();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值