在Java中,多线程编程的同步主要可以通过以下几种方式来实现:
synchronized关键字
同步方法:通过在方法声明中加入`synchronized`关键字,可以确保同一时刻只有一个线程能够执行该方法。
同步代码块:通过在代码块前加上`synchronized`关键字并指定一个锁对象,可以确保同一时刻只有一个线程能够执行该代码块。
示例代码:
```java
public class SyncMethodDemo {
private int count = 0;
public synchronized void addCount() {
count++;
}
public synchronized int getCount() {
return count;
}
}
public class SyncBlockDemo {
private int count = 0;
private final Object lock = new Object();
public void addCount() {
synchronized (lock) {
count++;
}
}
}
```
ReentrantLock接口
`ReentrantLock`是一个可重入的互斥锁,提供了比`synchronized`更加灵活和强大的线程同步机制。
可以实现公平锁和非公平锁,还可以实现可中断的锁获取操作等。
示例代码:
```java
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockDemo {
private final ReentrantLock lock = new ReentrantLock();
private int count = 0;
public void addCount() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
}
```
其他同步机制
wait():使一个线程处于等待状态,并且释放所持有的对象的`lock`。
notify():唤醒一个处于等待状态的线程,但唤醒哪个线程由JVM确定。
notifyAll():唤醒所有处于等待状态的线程,这些线程会竞争锁。
示例代码:
```java
public class WaitNotifyDemo {
private final Object lock = new Object();
private boolean ready = false;
public void producer() {
synchronized (lock) {
try {
while (!ready) {
lock.wait();
}
// 生产数据
ready = false;
lock.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void consumer() {
synchronized (lock) {
try {
while (ready) {
lock.wait();
}
// 消费数据
ready = true;
lock.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
```
总结
在Java多线程编程中,同步是一个重要的概念,用于防止多个线程同时访问共享资源导致的冲突或不一致问题。主要使用`synchronized`关键字和`ReentrantLock`接口来实现同步。同时,还可以使用`wait()`、`notify()`和`notifyAll()`方法来进行线程间的协作。开发者需要根据具体场景选择合适的同步机制,以确保程序的正确性和性能。