重入锁预防死锁的两种方式

重入锁ReentrantLock类似于synchronized,都可以让多个线程对临界区资源的访问进行控制,但重入锁需要手动释放锁,正是这样,重入锁更加的灵活;介绍重入锁防死锁的两种方式:

1.中断响应  lockInterruptibly():

import java.util.concurrent.locks.ReentrantLock;

/**
 * lockInterruptibly   可以响应中断   
 */
public class TestLockInterruptibly implements Runnable{
    private static ReentrantLock r1 = new ReentrantLock();
    private static ReentrantLock r2 = new ReentrantLock();
    private  int i;
    public TestLockInterruptibly(int i) {
        this.i = i;
    }
    @Override
    public void run(){
        if(i == 0){
                try {
                    r1.lockInterruptibly();
                    Thread.sleep(1000);
                    System.out.println("r1xxx start...");
                    try {
                        r2.lockInterruptibly();
                        System.out.println("r2xxx start....");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally{
                        if(r2.isHeldByCurrentThread()){
                            r2.unlock();
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally{
                    if(r1.isHeldByCurrentThread()){
                        r1.unlock();
                    }
                }
        }else{
                try {
                    r2.lockInterruptibly();
                    Thread.sleep(1000);
                    System.out.println("r2 start...");

                    try {
                        r1.lockInterruptibly();
                        System.out.println("r1 start...");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally{
                        if(r1.isHeldByCurrentThread()){
                            r1.unlock();
                        }
                    }
                } catch (InterruptedException e) {
                    System.out.println("被中断");
                }finally{
                    if(r2.isHeldByCurrentThread()){
                        r2.unlock();
                    }
                }
        }
    }


    public static void main(String[] args){
        TestLockInterruptibly k1 = new TestLockInterruptibly(0);
        TestLockInterruptibly k2 = new TestLockInterruptibly(1);
        Thread t1 = new Thread(k1, "t1");
        Thread t2 = new Thread(k2, "t2");
        t1.start();
        t2.start();
        t2.interrupt();
    }
}

控制台:

被中断
r1xxx start...
r2xxx start....

2.锁申请  tryLock():

import java.util.concurrent.locks.ReentrantLock;

/**
 * tryLock()  如果申请到锁  立即返回true  否则返回false   
 * tryLock(5, TimeUnit.Seconds) 可以接参数  一定时间内申请到锁
 * 返回true 否则返回false
 */
public class TestTryLock implements Runnable{
    private static ReentrantLock r1 = new ReentrantLock();  //此处必须是静态的  否则 main两个实例获取的不是一把锁
    private static ReentrantLock r2 = new ReentrantLock();
    private int i;

    public TestTryLock(int i ){
        this.i = i;
    }

    @Override
    public void run(){
        if(i == 0) {
                try {
                    if (r1.tryLock()) {
                        Thread.sleep(1000);
                        System.out.println(Thread.currentThread().getName() + "done r1 work..");
                        try {
                            if (r2.tryLock()) {
                                System.out.println(Thread.currentThread().getName() + "done r2 work...");
                                return;
                            }
                        } finally {
                            if (r2.isHeldByCurrentThread()) {
                                r2.unlock();
                            }
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    if (r1.isHeldByCurrentThread()) {
                        r1.unlock();
                    }
            }
        }else {
                try {
                    if (r2.tryLock()) {
                        Thread.sleep(1000);
                        System.out.println(Thread.currentThread().getName() + "done r2 work ...");
                        try {
                            if (r1.tryLock()) {
                                System.out.println(Thread.currentThread().getName() + "done r1 work...");
                                return;
                            }
                        } finally {
                            if (r1.isHeldByCurrentThread()) {
                                r1.unlock();
                            }
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    if (r2.isHeldByCurrentThread()) {
                        r2.unlock();
                    }
                }
        }
    }

    public static void main(String[] args){
        Thread t1 = new Thread(new TestTryLock(0), "t1");
        Thread t2 = new Thread(new TestTryLock(1), "t2");
        t1.start();
        t2.start();

    }
}
控制台:

t1done r1 work..
t2done r2 work ...
t2done r1 work...
 

--案例来源于java高并发程序设计

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值