线程间通信是指在多个线程之间传递数据和同步它们的执行。Java提供了几种线程间通信的办法,包含:

  1. 应用共享变量
  2. 应用wait()notify()notifyAll()
  3. 应用java.util.concurrent包中的工具类

5.4.1 应用共享变量

线程能够通过访问共享变量实现通信。为了确保线程平安,咱们须要对共享变量的拜访进行同步。咱们能够应用synchronized关键字来实现同步。

示例:两个线程通过共享变量实现通信

class SharedCounter {    private int counter = 0;    public synchronized void increment() {        counter++;        System.out.println("Counter: " + counter);    }}public class SharedVariableExample {    public static void main(String[] args) {        SharedCounter sharedCounter = new SharedCounter();        Thread t1 = new Thread(() -> {            for (int i = 0; i < 10; i++) {                sharedCounter.increment();            }        });        Thread t2 = new Thread(() -> {            for (int i = 0; i < 10; i++) {                sharedCounter.increment();            }        });        t1.start();        t2.start();    }}

在上述示例中,咱们创立了一个SharedCounter类,它有一个共享变量counter。两个线程通过调用increment()办法来递增计数器。咱们应用synchronized关键字确保了对计数器的同步拜访。

5.4.2 应用wait()notify()notifyAll()

wait()notify()notifyAll()java.lang.Object类的办法,能够用于在线程间实现通信。这些办法必须在同步代码块或同步办法中应用。

  • wait(): 使以后线程期待,直到其余线程调用此对象的notify()notifyAll()办法。调用wait()时,线程会开释锁,容许其余线程进入同步代码块或同步办法。
  • notify(): 唤醒期待此对象锁的单个线程。如果有多个线程在期待,只有一个线程会被唤醒。
  • notifyAll(): 唤醒期待此对象锁的所有线程。

示例:应用wait()notify()实现生产者-消费者问题

import java.util.LinkedList;import java.util.Queue;class ProducerConsumer {    private Queue<Integer> queue = new LinkedList<>();    private int maxSize;    public ProducerConsumer(int maxSize) {        this.maxSize = maxSize;    }    public void produce() throws InterruptedException {        int value = 0;        while (true) {            synchronized (this) {                while (queue.size() == maxSize) {                    wait();                }                System.out.println("Produced: " + value);                queue.offer(value++);                notify();                Thread.sleep(1000);            }        }    }    public void consume() throws InterruptedException {        while (true) {            synchronized (this) {                while (queue.isEmpty()) {                    wait();                }                int value = queue.poll();                System.out.println("Consumed: " + value);                notify();                Thread.sleep(1000);            }        }    }}public class WaitNotifyExample {    public static void main(String[] args) {        ProducerConsumer pc = new ProducerConsumer(5);        Thread producer = new Thread(() -> {            try {                pc.produce();            } catch (InterruptedException e) {                e.printStackTrace();            }        });        Thread consumer = new Thread(() -> {            try {                pc.consume();            } catch (InterruptedException e) {                e.printStackTrace();            }        });        producer.start();        consumer.start();    }}

在上述示例中,咱们实现了一个生产者-消费者问题。生产者线程和消费者线程通过共享队列进行通信。咱们应用wait()notify()办法来同步生产者和消费者的执行。

5.4.3 应用 java.util.concurrent 包中的工具类

java.util.concurrent 包提供了许多工具类,能够用于线程间的通信。这些类包含 SemaphoreCountDownLatchCyclicBarrierExchangerBlockingQueue 等。这些类提供了高级的同步和通信机制,能够简化多线程编程。

上面是应用 BlockingQueue 实现生产者-消费者问题的示例:

import java.util.concurrent.BlockingQueue;import java.util.concurrent.LinkedBlockingQueue;class Producer implements Runnable {    private final BlockingQueue<Integer> sharedQueue;    public Producer(BlockingQueue<Integer> sharedQueue) {        this.sharedQueue = sharedQueue;    }    @Override    public void run() {        for (int i = 0; i < 10; i++) {            try {                System.out.println("Produced: " + i);                sharedQueue.put(i);                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}class Consumer implements Runnable {    private final BlockingQueue<Integer> sharedQueue;    public Consumer(BlockingQueue<Integer> sharedQueue) {        this.sharedQueue = sharedQueue;    }    @Override    public void run() {        while (true) {            try {                int item = sharedQueue.take();                System.out.println("Consumed: " + item);                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}public class BlockingQueueExample {    public static void main(String[] args) {        BlockingQueue<Integer> sharedQueue = new LinkedBlockingQueue<>();        Thread producer = new Thread(new Producer(sharedQueue));        Thread consumer = new Thread(new Consumer(sharedQueue));        producer.start();        consumer.start();    }}

在这个示例中,咱们应用 BlockingQueue 实现生产者-消费者问题。BlockingQueue 是一个线程平安的队列,它提供了阻塞的 put() 和 take() 办法,能够在队列满或空时阻塞生产者或消费者线程。这样,咱们不再须要显式地应用 wait() 和 notify() 办法来同步线程。

小结

在本章节中,咱们探讨了Java多线程与并发的“5.4 线程间通信”。咱们理解了如何应用共享变量、wait()notify()notifyAll()以及java.util.concurrent包中的工具类实现线程间通信。

线程间通信是多线程编程中的要害概念,它能够帮忙咱们解决简单的同步和合作问题。把握这些办法对于编写高效的并发程序至关重要。

请务必多加实际,以便更好地把握这些知识点。祝你学习顺利!
举荐浏览:

https://mp.weixin.qq.com/s/dV2JzXfgjDdCmWRmE0glDA

https://mp.weixin.qq.com/s/an83QZOWXHqll3SGPYTL5g