重入锁的学习 (ReentrantLock)

重入锁  :(ReentrantLock)

  • 上锁 用reentrantLock.lock 方法 解锁 用reentrantLock.unlock 方法
  • 上锁和解锁 必须配对 可以多重上锁
  • ReentrantLock 是对 synchronized 的升级,synchronized 底层是通过 JVM 实现的,
  • ReentrantLock 是通过 JDK 实现的,使⽤起来更加简单。
  • 重⼊锁是指可以给同⼀个资源添加过个锁,并且解锁的⽅式与 synchronized 有区别,
  • synchronized 的锁是线程执⾏完毕之后⾃动释放,ReentrantLock 的锁是通过开发者⼿动释放的。
import java.util.concurrent.locks.ReentrantLock;

public class Account implements Runnable {
    private static int num;
    private ReentrantLock reentrantLock = new ReentrantLock();

    @Override
    public void run() {
//上锁
        reentrantLock.lock();
        reentrantLock.lock();
        num++;
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("您是第" + num + "位访客");
//解锁
        reentrantLock.unlock();
        reentrantLock.unlock();
    }
}

 

public class Test {
    public static void main(String[] args) {
        Account account = new Account();
        new Thread(account).start();
        new Thread(account).start();
    }
}

 

  • 重⼊锁可中断,是指某个线程在等待获取锁的过程中可以主动终⽌线程,lockInterruptibly()。
  • 重⼊锁具备限时性的特点,可以判断某个线程在⼀定的时间内能否获取锁。
  • boolean tryLock(long time,TimeUnit unit) time:时间数值 unit:时间单位
  • true 表示在该时段内能够获取锁,false 表示在该时段内⽆法获取锁。
  • 当判断的时间小于休眠的时间时不能获取锁 否则可以
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

public class TimeOut implements Runnable {
    private ReentrantLock reentrantLock = new ReentrantLock();

    @Override
    public void run() {
        try {
            if (reentrantLock.tryLock(6, TimeUnit.SECONDS)) {
                System.out.println(Thread.currentThread().getName() + "get lock");
                Thread.sleep(5000);
            } else {
                System.out.println(Thread.currentThread().getName() + "not lock");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        reentrantLock.unlock();
    }
}

 

public class Test01 {
    public static void main(String[] args) {
        TimeOut timeOut = new TimeOut();
        new Thread(timeOut,"线程1").start();
        new Thread(timeOut,"线程2").start();
    }
}

 

转载于:https://www.cnblogs.com/199600xcl/p/11301475.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
重入(ReentrantLock)是一种独占,也就是说同一时间只能有一个线程持有该。与 synchronized 关键字不同的是,重入可以支持公平和非公平两种模式,而 synchronized 关键字只支持非公平重入的实现原理是基于 AQS(AbstractQueuedSynchronizer)框架,利用了 CAS(Compare And Swap)操作和 volatile 关键字。 重入的核心思想是“可重入性”,也就是说如果当前线程已经持有了该,那么它可以重复地获取该而不会被阻塞。在重入内部,使用了一个计数器来记录当前线程持有该的次数。每当该线程获取一次时,计数器就加 1,释放一次时,计数器就减 1,只有当计数器为 0 时,其他线程才有机会获取该重入的基本使用方法如下: ```java import java.util.concurrent.locks.ReentrantLock; public class ReentrantLockTest { private static final ReentrantLock lock = new ReentrantLock(); public static void main(String[] args) { new Thread(() -> { lock.lock(); try { System.out.println(Thread.currentThread().getName() + " get lock"); Thread.sleep(1000L); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); System.out.println(Thread.currentThread().getName() + " release lock"); } }, "Thread-1").start(); new Thread(() -> { lock.lock(); try { System.out.println(Thread.currentThread().getName() + " get lock"); } finally { lock.unlock(); System.out.println(Thread.currentThread().getName() + " release lock"); } }, "Thread-2").start(); } } ``` 在上面的示例代码中,我们创建了两个线程,分别尝试获取重入。由于重入支持可重入性,因此第二个线程可以成功地获取到该,而不会被阻塞。当第一个线程释放后,第二个线程才会获取到并执行相应的操作。 需要注意的是,使用重入时一定要记得在 finally 块中释放,否则可能会导致死的问题。同时,在获取时也可以设置超时时间,避免由于获取失败而导致的线程阻塞问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值