并发安全笔记5——Lock

本文详细介绍了Java并发编程中Lock接口的使用,特别是ReentrantLock的实现。Lock提供了比synchronized更细粒度的锁控制,包括可中断的锁获取、尝试获取锁以及定时等待等功能。通过示例代码展示了如何使用lock()、unlock()、tryLock()以及lockInterruptibly()方法,并对比了Lock与synchronized的区别。强调了在使用Lock时,必须在finally块中释放锁以避免死锁。

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

Lock是J.U.C中提供解决线程同步问题的实现方式

Lock是一个接口

public interface Lock {
    void lock();
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    void unlock();
    Condition newCondition();
}

lock()方法是主要的使用方法,与之配合的是unLock()

eg

public class LockDemo {
    static Lock lock=new ReentrantLock();

    private static int count=0;
    public static void inc() throws InterruptedException {
        lock.lock();//抢占锁,如果没有抢占到,会阻塞
        Thread.sleep(1);
        count++;
        lock.unlock();
    }
    public static void main(String[] args) throws InterruptedException {
        for (int i=0;i<1000;i++){
            Thread thread=new Thread(()->{
                try {
                    LockDemo.inc();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            thread.start();
        }
        Thread.sleep(6000);
        System.out.println(count);
    }
}

使用lock()方法后,如果线程抢占到锁则执行,没有抢占到则阻塞。于synchronized关键字一个很大不不同是,lock可以主动释放锁,释放锁的方法就是unLock()。所以私用Lock一定要释放锁,不然就会造成死锁。通常推荐使用try()catch()finally的形式,在finally代码块里释放锁。

try{
    //处理任务
}catch(Exception ex){
     
}finally{
    lock.unlock();   //释放锁
}

tryLock()和tryLock(long time, TimeUnit unit)都是有返回值的

tryLock()表示当前线程是否抢占到锁,抢占到则返回true,没有则false。

tryLock(long time, TimeUnit unit)表示会等一段时间,如果在这段时间内抢占到则返回true,没有则false

tryLock尝试抢占锁时不会造成阻塞,没有抢占到立刻返回。

lockInterruptibly()表示通过这个方法获取锁时,如果线程正在等待获取锁,则这个县城能够响应中断,也就是中断这个线程的等待状态。当两个线程同时调用lock.lockInterruptibly()获取锁,假如此时A获取到了锁,而线程B只有等待,那么对线程B调用threadB.imterrupt()方法时就可以中断线程B的等待过程。同时需要抛出InterruptedException 。

public void method() throws InterruptedException {
    lock.lockInterruptibly();
    try {  
     //.....
    }
    finally {
        lock.unlock();
    }  
}

interrupt()方法是无法中断执行中线程的,所以这里的中断只能中断处于阻塞中的等待的线程。

synchronized关键字没办法中断一个处于等待的线程。

从以上也可以看出来synchronized与Lock的区别

  1. synchronized是Java提供的关键字,Lock是JUC中提供的接口
  2. synchronized可以作用于静态方法、实例方法、代码块。Lock是接口通过实现类来实现一个锁对象同加锁解锁来保证一段代码的线程安全问题
  3. synchronized阻塞的处于等待中的线程不能被中断,只能一直等待下去。Lock阻塞的线程可以被中断取消等待。

但他们都可以解决线程安全。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值