java 死锁_JAVA死锁的写法

在java开发中,避免不了要加锁控制程序逻辑,但加锁有可能导致死锁,造成线程永远卡死在等待释放锁,后面的代码得不到执行;

在java里,一般是通过synchronized关键字加锁,在jdk1.5版本中新增了Lock接口显示的加锁,本文讨论用这两种方式实现死锁;

方式一:

public static void main(String[] args) {

Object lock1 = new Object();

Object lock2 = new Object();

ExecutorService service = Executors.newCachedThreadPool();

service.execute(() ->{

while (true){

synchronized (lock2){

synchronized (lock1){

System.out.println("Thread1");

}

}

}

});

service.execute(() ->{

while (true){

synchronized (lock1){

synchronized (lock2){

System.out.println("Thread2");

}

}

}

});

service.shutdown();

}

上面的代码开启了两个线程,两个线程都循环打印字符串,正常来说两个线程都会不断打印,但这里出现了死锁,导致两个线程都会打印停止,逻辑分析:两个线程执行到某一时刻,线程一执行到synchronized (lock2){这一句,获得了对象lock2上的锁,线程二执行到synchronized (lock1){这一句,获得了对象lock1上的锁,接下来,线程一需要执行synchronized (lock1){这一句尝试获取lock1的锁,由于lock1的锁被线程二占用,线程一等待线程二释放lock1的锁,这时线程二需要执行synchronized (lock2){这一句,尝试获取lock2上的锁,由于lock2上的锁被线程一占用,线程二等待线程一释放lock2上的锁,这样,两个线程互相等待释放锁,导致两个线程永远无法执行后面的代码,导致死锁;

方式二:

static final Lock LOCK1 = new ReentrantLock();

static final Lock LOCK2 = new ReentrantLock();

public static void main(String[] args) {

ExecutorService service = Executors.newCachedThreadPool();

service.execute(new PrintTask1(1));

service.execute(new PrintTask2(2));

}

static class PrintTask1 implements Runnable{

private int id = -1;

public PrintTask1(int i){

id = i;

}

@Override

public void run() {

while (true){

LOCK1.lock();

LOCK2.lock();

System.out.println("" + id);

LOCK2.unlock();

LOCK1.unlock();

}

}

}

static class PrintTask2 implements Runnable{

private int id = -1;

public PrintTask2(int i){

id = i;

}

@Override

public void run() {

while (true){

LOCK2.lock();

LOCK1.lock();

System.out.println("" + id);

LOCK2.unlock();

LOCK1.unlock();

}

}

}

方式二的代码属于显示加锁,使用了jdk1.5新增的Lock接口,与方式一类似,当两个线程执行到某一时刻,线程一执行了LOCK1.lock()获得了LOCK1锁,线程二执行了LOCK2.lock()获得了LOCK2锁,接下来两个线程又要互相等待对方释放锁,导致死锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值