线程之间如何进行通讯的?

117 阅读2分钟

在Java中,线程之间的通讯主要通过以下几种方式实现:

  1. 使用共享对象进行通讯:线程之间可以通过操作同一个共享对象来实现通讯。比如,使用wait()notify()notifyAll()方法进行线程协调。

  2. 使用java.util.concurrent包中的工具类:例如,使用BlockingQueueCountDownLatchCyclicBarrierSemaphore等。

示例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