程序员求职经验分享与学习资料整理平台

网站首页 > 文章精选 正文

Java并发之旅:Lock, Condition & ReadWriteLock 的魔法

balukai 2025-07-10 13:09:03 文章精选 3 ℃

Locks

在Java中,除了使用synchronized关键字外,我们还可以使用
java.util.concurrent.locks包中的Lock接口和其实现类(如ReentrantLock)来创建锁。使用Lock可以提供比synchronized更高的灵活性。

实例代码


import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockExample {
    private final Lock lock = new ReentrantLock();

    public void performTask() {
        lock.lock();
        try {
            // critical section
            System.out.println("Task performed");
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        LockExample example = new LockExample();
        example.performTask();
    }
}

讲解:

在上面的代码中,我们使用ReentrantLock来替代synchronized块。当进入临界区时,我们调用lock()方法来获得锁,完成后使用unlock()方法释放锁。使用Lock的好处是它提供了更细粒度的控制,如尝试获取锁、定时锁等。

Condition

与传统的Object的wait()和notify()/notifyAll()方法相比,Condition接口提供了更丰富的线程同步操作。

实例代码

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConditionExample {
    private final Lock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();

    public void awaitCondition() throws InterruptedException {
        lock.lock();
        try {
            System.out.println("Waiting for the condition...");
            condition.await();
            System.out.println("Condition met!");
        } finally {
            lock.unlock();
        }
    }

    public void signalCondition() {
        lock.lock();
        try {
            System.out.println("Signaling condition...");
            condition.signal();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ConditionExample example = new ConditionExample();

        Thread thread1 = new Thread(() -> {
            try {
                example.awaitCondition();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread thread2 = new Thread(example::signalCondition);

        thread1.start();
        Thread.sleep(1000); // Just to ensure thread1 starts before thread2
        thread2.start();
    }
}

讲解:

在上面的代码中,我们使用Condition来同步两个线程。线程1等待条件满足,而线程2发出条件已满足的信号。这与使用wait()和notify()类似,但Condition提供了更多的灵活性。

ReadWriteLock

ReadWriteLock是一个接口,它包含了两个锁,一个用于读操作,另一个用于写操作。这允许多个线程同时读,但只允许一个线程写。

实例代码


import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockExample {
    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
    private int data = 0;

    public int readData() {
        rwLock.readLock().lock();
        try {
            System.out.println("Read data: " + data);
            return data;
        } finally {
            rwLock.readLock().unlock();
        }
    }

    public void writeData(int value) {
        rwLock.writeLock().lock();
        try {
            System.out.println("Write data: " + value);
            data = value;
        } finally {
            rwLock.writeLock().unlock();
        }
    }

    public static void main(String[] args) {
        ReadWriteLockExample example = new ReadWriteLockExample();

        Thread writer = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                example.writeData(i);
            }
        });

        Thread reader = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                example.readData();
            }
        });

        writer.start();
        reader.start();
    }
}

讲解:

在上述代码中,我们使用ReentrantReadWriteLock来实现ReadWriteLock。当我们只读取数据时,可以有多个读线程同时进行,但当我们写数据时,只有一个线程可以写,同时不允许其他线程读。

最近发表
标签列表