线程间通信是指在多个线程之间传递数据和同步它们的执行。Java 提供了几种线程间通信的办法,包含:
- 应用共享变量
- 应用
wait()
、notify()
和notifyAll()
- 应用
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
包提供了许多工具类,能够用于线程间的通信。这些类包含 Semaphore
、CountDownLatch
、CyclicBarrier
、Exchanger
、BlockingQueue
等。这些类提供了高级的同步和通信机制,能够简化多线程编程。
上面是应用 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