Java中线程同步问题:锁、条件变量与问题实例
在Java中,线程同步是一个重要的概念,它确保了多个线程在访问共享资源时的一致性和线程安全。以下是一些常见的线程同步机制和它们的基本用法:
1.锁(Locks)
Java提供了多种锁机制,其中最基本的是synchronized
关键字和ReentrantLock
类。
synchronized关键字:可以用来修饰方法或者代码块,确保同一时间只有一个线程可以执行该段代码。
```java public class Counter {
private int count =0;public synchronized void increment() {
count++;
}public synchronized int getCount() {
return count;
}
}- **ReentrantLock类**:是一个可重入的互斥锁,提供了与`synchronized`关键字类似的同步功能,但提供了更灵活的加锁和解锁操作。
javaimport java.util.concurrent.locks.ReentrantLock;public class Counter {
private final ReentrantLock lock = new ReentrantLock();
private int count =0;public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}public int getCount() {
lock.lock();
try {
return count;
} finally {
lock.unlock();
}
}
}
```###2.条件变量(Condition Variables)
条件变量允许一个线程在某个条件为真之前挂起,并在条件变为真时被唤醒。Condition
接口和ReentrantLock
类一起使用。
```javaimport java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class BoundedBuffer {
private final Object[] items;
private int putPtr, takePtr, count;
private final ReentrantLock lock = new ReentrantLock();
private final Condition notEmpty = lock.newCondition();
private final Condition notFull = lock.newCondition();
public BoundedBuffer(int capacity) {
items = new Object[capacity];
}
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length) {
notFull.await();
}
items[putPtr] = x;
if (++putPtr == items.length) putPtr =0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count ==0) {
notEmpty.await();
}
Object x = items[takePtr];
if (++takePtr == items.length) takePtr =0;
—count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}
```###问题实例一个常见的线程同步问题是死锁,当两个或多个线程在等待对方释放资源时发生。例如:
```javapublic class DeadlockExample {
private static final Object resource1 = new Object();
private static final Object resource2 = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (resource1) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resource2) {
System.out.println(“Thread1 acquired both resources”);
}
}
}).start();
new Thread(() -> {
synchronized (resource2) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resource1) {
System.out.println(“Thread2 acquired both resources”);
}
}
}).start();
}
}
```在这个例子中,两个线程分别尝试获取两个资源,但由于它们获取资源的顺序不同,导致死锁。
线程同步是并发编程中的一个重要话题,正确使用同步机制可以避免数据不一致和死锁等问题。
还没有评论,来说两句吧...