在Java中,线程之间的通讯主要通过以下几种方式实现:
-
使用共享对象进行通讯:线程之间可以通过操作同一个共享对象来实现通讯。比如,使用
wait()、notify()和notifyAll()方法进行线程协调。 -
使用
java.util.concurrent包中的工具类:例如,使用BlockingQueue、CountDownLatch、CyclicBarrier、Semaphore等。
示例1
下面是使用共享对象和wait()、notify()方法进行线程通讯的具体示例代码:
class SharedResource {
private String message;
private boolean hasMessage = false;
public synchronized void putMessage(String message) {
while (hasMessage) {
try {
wait(); // 等待直到消息被消费
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
this.message = message;
hasMessage = true;
System.out.println("Produced: " + message);
notifyAll(); // 通知等待消费的线程
}
public synchronized String getMessage() {
while (!hasMessage) {
try {
wait(); // 等待直到有消息生产
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
hasMessage = false;
System.out.println("Consumed: " + message);
notifyAll(); // 通知等待生产的线程
return message;
}
}
class Producer implements Runnable {
private SharedResource sharedResource;
public Producer(SharedResource sharedResource) {
this.sharedResource = sharedResource;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
sharedResource.putMessage("Message " + i);
try {
Thread.sleep(100); // 模拟生产耗时
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
class Consumer implements Runnable {
private SharedResource sharedResource;
public Consumer(SharedResource sharedResource) {
this.sharedResource = sharedResource;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
sharedResource.getMessage();
try {
Thread.sleep(150); // 模拟消费耗时
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
public class ThreadCommunicationExample {
public static void main(String[] args) {
SharedResource sharedResource = new SharedResource();
Thread producerThread = new Thread(new Producer(sharedResource));
Thread consumerThread = new Thread(new Consumer(sharedResource));
producerThread.start();
consumerThread.start();
}
}
在这个示例中,SharedResource类包含一个消息和状态标志,Producer线程生产消息,Consumer线程消费消息。wait()和notifyAll()用于线程之间的协调。
示例2
以下是使用BlockingQueue实现线程通讯的示例:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
class Producer implements Runnable {
private BlockingQueue<String> queue;
public Producer(BlockingQueue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
queue.put("Message " + i);
System.out.println("Produced: Message " + i);
Thread.sleep(100); // 模拟生产耗时
}
queue.put("DONE");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
class Consumer implements Runnable {
private BlockingQueue<String> queue;
public Consumer(BlockingQueue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
try {
while (true) {
String message = queue.take();
if (message.equals("DONE")) {
break;
}
System.out.println("Consumed: " + message);
Thread.sleep(150); // 模拟消费耗时
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
public class BlockingQueueExample {
public static void main(String[] args) {
BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
Thread producerThread = new Thread(new Producer(queue));
Thread consumerThread = new Thread(new Consumer(queue));
producerThread.start();
consumerThread.start();
}
}
在这个示例中,BlockingQueue用于在生产者和消费者线程之间传递消息,生产者将消息放入队列,消费者从队列中取出消息。
小结
| 方法 | 描述 | 示例代码位置 |
|---|---|---|
共享对象 + wait/notify | 通过共享对象的标志位和wait()、notify()方法协调线程运行 | 第一个示例代码 |
BlockingQueue | 使用Java提供的阻塞队列,在生产者和消费者之间传递数据 | 第二个示例代码 |
CountDownLatch | 一个线程等待其他线程完成各自的工作后再继续执行 | - |
CyclicBarrier | 一组线程互相等待,达到一个共同的屏障点后再继续执行 | - |
Semaphore | 控制对某个资源的访问线程数 | - |
欢迎访问我的(夏壹分享)公众号 和 博客(sanzhishu)后缀top