Lock接口和ReadWriteLock接口

本文详细介绍了Java中Lock接口的功能及使用方法,包括其六个核心方法的解释,并深入探讨了ReentrantLock作为Lock接口实现的具体机制。同时,文章对比了排他锁与读写锁的不同之处,展示了读写锁如何通过分离读锁和写锁来提高并发性能。

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

Lock接口

Lock接口在java.util.concurrent.locks包中,在jdk1.5之后才有。

Lock接口有6个方法:

void lock();

void lockInterruptibly() throws InterruptedException;

Condition newCondition();

boolean tryLock();

boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

void unlock();

Lock接口有一个实现类ReentrantLock。reentrant中文意思是可重入的。可重入锁能够支持一个线程对资源的重复加锁,注意是同一个线程的重复加锁,不是多个线程的加锁。此外,可重入锁还支持公平的或者非公平的选择获取锁的线程。

其实synchronized关键字也是可重入的,支持同步代码块或者同步方法的嵌套。

ReentrantLock有3个静态内部类:Sync、NonfairSync、FairSync,具体如下:

java.util.concurrent.locks.ReentrantLock.Sync是继承AbstractQueuedSynchronizer(队列同步器,以下简称同步器)抽象类的抽象类,有一个抽象的void lock();方法。这里需要提醒下,AbstractQueuedSynchronizer虽然是抽象类,但是该类没有抽象方法,其实完全可以不定义成抽象类。

java.util.concurrent.locks.ReentrantLock.NonfairSync和java.util.concurrent.locks.ReentrantLock.FairSync都是Sync的子类,前者是非公平同步实现,后者是公平同步实现,这两个类均重写了Sync的lock()方法和AbstractQueuedSynchronizer的tryAcquire(int acquires)方法。ReentrantLock实例的lock()方法内部就是调用Sync实例的lock()方法,具体是NonfairSync实例还是FairSync实例,要看构造ReentrantLock实例时传的参数,如果传入的是true,则是公平可重入锁,如果传的是false,则是非公平可重入锁。无参构造出来的是非公平的。非公平可重入锁相对于公平可重入锁,效率高很多,TPS高很多,因为相对来说少了大量的线程切换。

ReentrantLock用法示例:

public class ReentrantLockTest extends Thread {
    public static ReentrantLock lock = new ReentrantLock();
    public static int i = 0;

    public ReentrantLockTest(String name) {
        super.setName(name);
    }

    public static void main(String[] args) throws InterruptedException {
        ReentrantLockTest test1 = new ReentrantLockTest("thread1");
        ReentrantLockTest test2 = new ReentrantLockTest("thread2");
        test1.start();
        test2.start();
        test1.join();
        test2.join();
        System.out.println("main terminate");
    }

    @Override
    public void run() {
        for (int j = 0; j < 10; j++) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock.lock();
            try {
                System.out.println("lock=" + lock + ", name=" + this.getName() + " ,i=" + i);
                i++;
            } finally {
                lock.unlock();
            }
        }
    }
}
View Code

ReadWriteLock接口

synchronized锁和Lock都是排他锁,这些锁在同一时刻只允许一个线程访问。而读写锁ReadWriteLock在同一时刻可以允许多个读线程访问,但是在写线程访问时,所有的读线程和其他写线程均被阻塞。读写锁维护了一对锁,一个读锁和一个写锁,通过分离读锁和写锁,使得并发性相对于一般的排他锁有很大的提升。

ReadWriteLock接口只有两个方法:

Lock readLock();

Lock writeLock();

ReadWriteLock接口的实现类是ReentrantReadWriteLock。ReentrantReadWriteLock类有100个静态内部类:

java.util.concurrent.locks.ReentrantReadWriteLock.Sync:

java.util.concurrent.locks.ReentrantReadWriteLock.NonfairSync:

java.util.concurrent.locks.ReentrantReadWriteLock.FairSync:

java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock:

java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock:

转载于:https://www.cnblogs.com/koushr/p/5873411.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值