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。当我们只读取数据时,可以有多个读线程同时进行,但当我们写数据时,只有一个线程可以写,同时不允许其他线程读。