线程间的通信
今天,作为一个大二小白的我,学习了线程间的通信,线程间的通信有生产者线程和消费者线程,还有资源(通信)。这里我们用商家卖苹果比喻生产者线程,客户买苹果比喻消费者线程,篮子作为资源,如下图所示:
生产者生产水果,如果水果没有被买走那么就不生产,生产者处于等待状态,如果水果被消费者买走的时候消费者会通知生产者告诉他,我们已经把水果买走了请生产,消费者同理,如果水果已经生产出来那么就买走,买走之后再通知生产者水果已经没了请生产。
所有我们这里需要创建的类一共有4个,线程类2个,资源类1个,测试类1个
1.线程类有:生产者线程
消费者线程
2.资源类:Basket(篮子)
3.测试类:Test
1.篮子资源类
//创建资源类篮子
public class Basket {
//isEmpty这个属性判断篮子是否为空,初始值设置为空
private boolean isEmpty = true;
//调用set和get方法
public boolean isEmpty() {
return isEmpty;
}
public void setEmpty(boolean empty) {
isEmpty = empty;
}
}
2.生产者线程
//生产者类需要继承Thread类,重写run方法
public class ProThread extends Thread{
private Basket basket;
//给个构造器,使basket传过来
public ProThread(Basket basket) {
this.basket = basket;
}
@Override
public void run() {
//给个死循环,一直跑
while (true) {
//给资源上锁
synchronized (basket) {
//判断basket篮子是否为空,如果不为空就要执行wait
if (!basket.isEmpty()) {
try {
//这里给个休眠
Thread.sleep(1000);
//让线程进入阻塞状态,调用wait()需要处理一下错误
basket.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
//如果basket等于空,生产苹果放到篮子里
System.out.println("生产苹果---");
//篮子满了,basket要设置为false,即篮子不为空
basket.setEmpty(false);
//唤醒消费者购买
basket.notify();
}
}
}
}
}
3.消费者线程
public class BuyThread extends Thread {
private Basket basket;
//给个构造器
public BuyThread(Basket basket) {
this.basket = basket;
}
@Override
public void run() {
while (true) {
synchronized (basket) {
//判断basket是否为空,如果篮子为空,消费者就不能购买所有要执行wait方法
if (basket.isEmpty()) {
try {
Thread.sleep(1000);
basket.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
//如果不为空,消费者就可以购买苹果
System.out.println("消费者买苹果");
//消费者买完苹果,这里要把篮子设置回空
basket.setEmpty(true);
//唤醒生产者生产
basket.notify();
}
}
}
}
}
4.测试类Test
public class Test {
public static void main(String[] args) {
//创建篮子资源
Basket b = new Basket();
//创建生产者线程,把资源p传过来
ProThread pr = new ProThread(b);
//创建消费者线程,把资源p传过来
BuyThread br = new BuyThread(b);
//运行线程
pr.start();
br.start();
}
}
注意:
1.线程间的通信共享数据一定要有同步代码块synchronize
2.一定要有wait和notify,而且二者一定是成对出现。
2.生产者和消费者的线程实现一定是在while(true)里面
以上笔记有错,请大神评论指定,谢谢!