下面我将为您详细讲解“Java中实现线程间通信的实例教程”的完整攻略。
什么是线程间通信
线程是 Java 中最基本的并发编程单元,线程之间的通信是指多个线程在访问共享资源过程中,通过某种协作机制对资源实现共享和互斥访问的过程。线程间通信是 Java 并发编程中的核心概念之一。
线程间通信实现方式
Java 中实现线程间通信一般有三种方式:
- 共享内存
- 消息传递
- 管程法
在本教程中,我们将主要通过消息传递和管程法来实现线程间的通信。
消息传递实现线程间通信
使用消息传递实现线程间通信需要依赖于 Java 中提供的两个类,即 wait()
和 notify()
方法。其中,wait()
方法会使当前线程等待,直到另一个线程调用该对象的 notify()
或 notifyAll()
方法通知该线程等待结束。通知时可以通过锁机制唤醒一个等待中的线程,也可唤醒全部等待中的线程。
接下来,我们将通过一个生产者和消费者的例子来说明如何使用消息传递实现线程间的通信:
class Store {
private int i = 0;
public synchronized void put() {
while (i >= 5) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " put " + (++i));
notifyAll();
}
public synchronized void get() {
while (i <= 0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " get " + (i--));
notifyAll();
}
}
class Producer implements Runnable {
private Store store;
public Producer(Store store) {
this.store = store;
}
@Override
public void run() {
while (true) {
store.put();
}
}
}
class Consumer implements Runnable {
private Store store;
public Consumer(Store store) {
this.store = store;
}
@Override
public void run() {
while (true) {
store.get();
}
}
}
public class MessageCommunicationDemo {
public static void main(String[] args) {
Store store = new Store();
new Thread(new Producer(store)).start();
new Thread(new Consumer(store)).start();
new Thread(new Producer(store)).start();
new Thread(new Consumer(store)).start();
}
}
上面的代码中,Store 类代表一个仓库,具有 put()
和 get()
方法,其中 put()
方法将商品放入仓库中,get()
方法将商品从仓库中取出。由于仓库中的商品数量有极限,因此在 put()
或 get()
方法中,首先判断商品是否已经满了或空了,如果是,则调用 wait()
方法将线程挂起,直到其他线程唤醒。当商品数量发生变化时,调用 notifyAll()
方法唤醒其他线程继续运行。
通过该例子,我们可以清楚的了解到通过消息传递实现线程间的通信的详细过程。
管程法实现线程间通信
管程是一种结构,包含共享变量及操作这些变量的过程,其中,共享变量一般配合条件变量使用以实现同步。Java 中的管程是通过 synchronized
和 wait()
、notify()
方法来实现的。当一个线程需要调用管程时,需要持有该管程的锁。当需要等待某个条件满足时,线程可以通过 wait()
方法将自己挂起,当条件被满足时,其他线程调用 notify()
方法,唤醒之前挂起的线程继续执行。管程法比消息传递的实现方式更加简单。
接下来,我们将通过一个银行取款的例子来说明如何使用管程法实现线程间的通信:
class Account {
private int balance = 100;
public synchronized void withdraw(int amount) {
while (balance < amount) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
balance -= amount;
System.out.println(Thread.currentThread().getName() + " withdraw " + amount + ", balance is " + balance);
}
public synchronized void deposit(int amount) {
balance += amount;
System.out.println(Thread.currentThread().getName() + " deposit " + amount + ", balance is " + balance);
notifyAll();
}
}
class WithdrawThread implements Runnable {
private Account account;
public WithdrawThread(Account account) {
this.account = account;
}
@Override
public void run() {
while (true) {
account.withdraw(70);
}
}
}
class DepositThread implements Runnable {
private Account account;
public DepositThread(Account account) {
this.account = account;
}
@Override
public void run() {
while (true) {
account.deposit(100);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class PipeCommunicationDemo {
public static void main(String[] args) {
Account account = new Account();
new Thread(new WithdrawThread(account)).start();
new Thread(new DepositThread(account)).start();
}
}
上面的代码中,Account 类代表一个银行账户,具有 withdraw()
和 deposit()
方法,其中 withdraw()
方法用于从账户中取款,deposit()
方法用于往账户中存款。由于账户中的余额可能不足,因此在 withdraw()
方法中,要判断余额是否充足,如果不足则调用 wait()
方法挂起线程,等待其他线程存款后余额增加。当余额充足时,其他线程通过 notifyAll()
方法唤醒之前挂起的线程继续执行。
通过该例子,我们可以清楚的了解到通过管程法实现线程间的通信的详细过程。
以上就是 Java 中实现线程间通信的完整攻略。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java中实现线程间通信的实例教程 - Python技术站