Java 多线程实现线程间的交互
引言
在并发编程中,多线程的交互是常见的需求。Java 提供了多种机制来实现线程间的交互,包括共享变量、锁、信号量等。本文将介绍一些常用的方法,并通过代码示例展示其用法。
共享变量
共享变量是多线程之间最简单的交互方式。多个线程可以共享相同的变量,并通过对该变量的读写操作来进行信息的传递。
在 Java 中,我们可以使用 volatile
关键字来声明共享变量。volatile
关键字可以确保变量对所有线程的可见性,即使发生了写操作,其他线程也能立即看到最新的值。
public class SharedVariableExample {
private volatile boolean flag = false;
public void setFlag(boolean value) {
flag = value;
}
public boolean getFlag() {
return flag;
}
}
上述代码中,flag
是一个共享变量,通过 setFlag
和 getFlag
方法可以对其进行读写操作。由于 flag
使用了 volatile
关键字修饰,所以对其进行写操作后,其他线程可以立即看到最新的值。
锁
锁是一种常用的线程间交互机制,通过加锁和解锁实现对共享资源的互斥访问。Java 提供了 synchronized
关键字和 ReentrantLock
类来实现锁的功能。
synchronized 关键字
synchronized
关键字可以用来修饰方法或代码块,实现对共享资源的同步访问。当一个线程进入被 synchronized
修饰的方法或代码块时,会自动获取相应的锁,其他线程将无法同时进入该方法或代码块。
public class SynchronizedExample {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized void decrement() {
count--;
}
}
上述代码中,increment
和 decrement
方法都使用了 synchronized
关键字修饰,保证了对 count
变量的互斥访问。当一个线程调用 increment
方法时,其他线程无法同时调用该方法,直到该线程释放锁。
ReentrantLock 类
ReentrantLock
类是 Java 提供的另一种锁的实现方式,相比于 synchronized
关键字,它提供了更多的灵活性和功能。
public class ReentrantLockExample {
private Lock lock = new ReentrantLock();
private int count = 0;
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
public void decrement() {
lock.lock();
try {
count--;
} finally {
lock.unlock();
}
}
}
上述代码中,increment
和 decrement
方法使用了 ReentrantLock
类来实现锁的功能。在进入和离开临界区时,通过调用 lock
和 unlock
方法来获取和释放锁。
信号量
信号量是一种更高级的线程间交互机制,它可以用来控制同时访问某个共享资源的线程数量。
Java 提供了 Semaphore
类来实现信号量。
public class SemaphoreExample {
private Semaphore semaphore = new Semaphore(3);
public void acquireResource() throws InterruptedException {
semaphore.acquire();
try {
// 访问共享资源
} finally {
semaphore.release();
}
}
}
上述代码中,Semaphore
类的构造方法需要传入一个初始的信号量数量。在调用 acquire
方法时,如果信号量数量为 0,线程将被阻塞,直到有其他线程释放了一个信号量。
总结
本文介绍了 Java 中多线程实现线程间交互的几种常见方式,包括共享变量、锁和信号量。共享变量是最简单的交互方式,通过对共享变量的读写来传递信息。锁可以保证共享资源