Java锁

1.synchronized关键字

synchronized是Java中最常用的锁机制之一,它可以实现线程同步和互斥。它可以用在方法和代码块上,语法如下:

public synchronized void method1() {
    // 方法体
}

public void method2() {
    synchronized (this) {
        // 代码块
    }
}

synchronized关键字可以保证同一时刻只有一个线程可以执行被锁定的代码段,其他线程必须等待锁释放后才能执行。但synchronized有一个缺点,即不支持中断。

2.ReentrantLock锁

private ReentrantLock lock = new ReentrantLock();

public void method() {
    lock.lock();
    try {
        // 代码块
    } finally {
        lock.unlock();
    }
}

ReentrantLock有一个特点,即它支持重入锁。也就是说,同一个线程可以重复获取同一个锁,这样可以避免死锁等问题。

3.ReadWriteLock锁

ReadWriteLock是一种特殊的锁,它可以让多个线程同时读取共享数据,但只允许一个线程写入数据。这种锁可以提高程序的并发性能,因为读取操作不会被阻塞。使用ReadWriteLock需要先获取读写锁,然后再进行相应的操作。

private ReadWriteLock lock = new ReentrantReadWriteLock();
private Lock readLock = lock.readLock();
private Lock writeLock = lock.writeLock();

public void read() {
    readLock.lock();
    try {
        // 读取数据
    } finally {
        readLock.unlock();
    }
}

public void write() {
    writeLock.lock();
    try {
        // 写入数据
    } finally {
        writeLock.unlock();
    }
}

4.StampedLock锁

StampedLock是Java中的一种新锁机制,它类似于ReadWriteLock,但比它更快。它支持读写锁和乐观读锁,乐观读锁比读锁更快,因为不需要获取锁。使用StampedLock需要先获取锁戳(stamp),然后再进行相应的操作。

private StampedLock lock = new StampedLock();

public void read() {
    long stamp = lock.tryOptimisticRead();
    // 读取数据
    if (!lock.validate(stamp)) {
        stamp = lock.readLock();
        try {
            // 读取数据
        } finally {
            lock.unlockRead(stamp);
        }
    }
}

public void write() {
    long stamp = lock.writeLock();
    try {
        // 写入数据
    } finally {
        lock.unlockWrite(stamp);
    }
}

5.Condition锁

Condition是基于Lock锁的等待/通知机制,它可以让线程在特定条件下等待或唤醒。使用Condition需要先获取锁,然后再创建相应的Condition对象,最后在等待或通知时使用该对象。示例代码如下:

private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();

public void method() {
    lock.lock();
    try {
        while (condition不满足) {
            condition.await();
        }
        // 执行操作
        condition.signalAll();
    } finally {
        lock.unlock();
    }
}

6.Semaphore锁

Semaphore是计数信号量,它可以控制同时访问某个资源的线程数量。Semaphore有两个常用的方法,acquire()和release(),分别表示获取许可证和释放许可证。使用Semaphore需要创建一个Semaphore对象,并指定许可证的数量。示例代码如下:

private Semaphore semaphore = new Semaphore(10);

public void method() {
    try {
        semaphore.acquire();
        // 执行操作
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        semaphore.release();
    }
}

7.CountDownLatch锁

CountDownLatch是倒计时锁,它可以让一个或多个线程等待其他线程完成某些任务后再执行。该锁有一个计数器,初始值为任务数量,每个任务完成后计数器减1,当计数器为0时,所有等待线程才能继续执行。使用CountDownLatch需要先创建一个CountDownLatch对象,并在执行任务的线程中调用countDown()方法,表示任务已完成。示例代码如下:

private CountDownLatch latch = new CountDownLatch(10);

public void method() {
    try {
        // 执行任务
        latch.countDown();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public void waitAllTasks() {
    try {
        latch.await();
        // 所有任务已完成,可以继续执行
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
posted @   杨葱头  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示