Java类库中的线程同步与互斥控制
Java类库中的线程同步与互斥控制
在多线程编程中,线程同步与互斥控制是非常重要的概念。当多个线程同时访问共享资源时,可能会发生数据竞争或争用条件,导致程序出现不确定的结果。Java类库提供了一些工具和机制来帮助开发人员实现线程同步与互斥控制,确保多线程程序的正确性和可靠性。
1. synchronized关键字
synchronized关键字用于修饰方法或代码块,确保在同一时间只能有一个线程访问被修饰的代码。当一个线程获得synchronized代码块的锁时,其他线程将被阻塞,直到该线程释放锁。这种机制可以保证共享资源在同一时间只被一个线程进行访问。以下是synchronized关键字的一个示例:
public class Counter {
private int count;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
在上面的例子中,Counter类使用synchronized关键字修饰了`increment()`和`getCount()`方法,确保在同一时间只有一个线程能够访问它们。
2. Lock接口与ReentrantLock类
Java还提供了Lock接口和ReentrantLock类来实现线程同步与互斥控制。与synchronized关键字相比,Lock接口提供了更大的灵活性和功能。以下是Lock接口与ReentrantLock类的示例:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Counter {
private int count;
private Lock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
public int getCount() {
lock.lock();
try {
return count;
} finally {
lock.unlock();
}
}
}
在上述示例中,Counter类使用了Lock接口和ReentrantLock类来实现线程同步与互斥控制。通过调用`lock()`方法获取锁,然后在`try-finally`块中执行对共享资源的操作,最后在`finally`块中释放锁。
3. Condition接口与ReentrantLock使用Condition
通过Condition接口可以与ReentrantLock类结合使用,实现更复杂的线程同步与互斥控制。Condition对象可以返回多个Condition实例以控制不同的线程调度。以下是Condition接口与ReentrantLock的使用示例:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Buffer {
private String[] buffer;
private int count;
private int putIndex;
private int takeIndex;
private Lock lock = new ReentrantLock();
private Condition notFull = lock.newCondition();
private Condition notEmpty = lock.newCondition();
public Buffer(int size) {
buffer = new String[size];
}
public void put(String message) throws InterruptedException {
lock.lock();
try {
while (count == buffer.length) {
notFull.await();
}
buffer[putIndex] = message;
putIndex = (putIndex + 1) % buffer.length;
count++;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public String take() throws InterruptedException {
lock.lock();
String message;
try {
while (count == 0) {
notEmpty.await();
}
message = buffer[takeIndex];
takeIndex = (takeIndex + 1) % buffer.length;
count--;
notFull.signal();
} finally {
lock.unlock();
}
return message;
}
}
在上面的示例中,Buffer类使用Condition接口与ReentrantLock类一起使用,实现了一个有限大小的缓冲区。通过调用`await()`方法释放锁并等待条件满足,然后通过调用`signal()`方法唤醒等待线程。
以上是Java类库中线程同步与互斥控制的一些常用机制和示例。多线程编程中正确处理线程同步与互斥控制非常重要,以确保程序的正确性和可靠性。