在Java中,线程之间的通信主要通过共享内存和线程同步机制来实现。常见的线程通信方式包括使用共享变量、wait
和notify
/notifyAll
方法、Condition
接口以及BlockingQueue
。共享变量通过同步机制保护访问,wait
和notify
/notifyAll
通过等待和通知机制实现通信,Condition
接口提供更灵活的等待和通知机制,而BlockingQueue
通过线程安全的队列实现生产者-消费者模式。
1. 共享变量
最简单的线程通信方式是通过共享变量。多个线程可以访问和修改同一个变量,从而实现信息的传递。为了确保线程安全,通常需要使用同步机制(如synchronized
关键字或Lock
接口)来保护共享变量的访问。
示例代码
public class SharedVariableExample {
private static int sharedVariable = 0;
public static void main(String[] args) {
Thread writerThread = new Thread(() -> {
synchronized (SharedVariableExample.class) {
sharedVariable = 1;
System.out.println("Writer thread set shared variable to 1");
}
});
Thread readerThread = new Thread(() -> {
synchronized (SharedVariableExample.class) {
System.out.println("Reader thread read shared variable: " + sharedVariable);
}
});
writerThread.start();
readerThread.start();
}
}
2. wait
和 notify
/notifyAll
wait
、notify
和notifyAll
方法是Object
类的方法,用于线程之间的等待和通知机制。一个线程调用wait
方法后会进入等待状态,直到另一个线程调用相同对象的notify
或notifyAll
方法来唤醒它。
示例代码
public class WaitNotifyExample {
private static final Object lock = new Object();
private static boolean ready = false;
public static void main(String[] args) {
Thread producerThread = new Thread(() -> {
synchronized (lock) {
ready = true;
System.out.println("Producer thread is ready.");
lock.notify();
}
});
Thread consumerThread = new Thread(() -> {
synchronized (lock) {
while (!ready) {
try {
System.out.println("Consumer thread is waiting.");
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consumer thread received notification and is ready.");
}
});
consumerThread.start();
producerThread.start();
}
}
3. Condition
接口
Condition
接口是java.util.concurrent.locks
包中的一个接口,提供了比wait
和notify
更灵活的线程通信机制。它通常与ReentrantLock
一起使用。
示例代码
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionExample {
private static final Lock lock = new ReentrantLock();
private static final Condition condition = lock.newCondition();
private static boolean ready = false;
public static void main(String[] args) {
Thread producerThread = new Thread(() -> {
lock.lock();
try {
ready = true;
System.out.println("Producer thread is ready.");
condition.signal();
} finally {
lock.unlock();
}
});
Thread consumerThread = new Thread(() -> {
lock.lock();
try {
while (!ready) {
try {
System.out.println("Consumer thread is waiting.");
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Consumer thread received notification and is ready.");
} finally {
lock.unlock();
}
});
consumerThread.start();
producerThread.start();
}
}
4. BlockingQueue
BlockingQueue
是java.util.concurrent
包中的一个接口,提供了线程安全的队列实现。生产者线程可以向队列中添加元素,消费者线程可以从队列中取出元素,从而实现线程之间的通信。
示例代码
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class BlockingQueueExample {
private static final BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
public static void main(String[] args) {
Thread producerThread = new Thread(() -> {
try {
queue.put(1);
System.out.println("Producer thread produced 1");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread consumerThread = new Thread(() -> {
try {
int value = queue.take();
System.out.println("Consumer thread consumed " + value);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
producerThread.start();
consumerThread.start();
}
}
总结
- 共享变量:通过同步机制保护共享变量的访问,实现线程之间的通信。
wait
和notify
/notifyAll
:通过等待和通知机制实现线程之间的通信。Condition
接口:提供更灵活的等待和通知机制,通常与ReentrantLock
一起使用。BlockingQueue
:通过线程安全的队列实现生产者-消费者模式,实现线程之间的通信。