线程通信
处理原因:
多个线程并发执行,CPU默认随机切换线程,当处理同一任务时,更好的有规律的调度,需要线程通信,避免对同一共享变量的争夺,使用的手段为:等待唤醒机制
等待唤醒机制
线程之间的通信,更加有效的利用资源
唤醒一般是唤醒等待时间最长的线程
- 能获取锁,线程就从WAITING --> RUNNABLE
- 否则,从wait set出来,又进入entry set,线程WAITING --> BLOCKED
调用wait和notify方法需要注意的细节
案例
包子铺线程和包子线程关系 --> 通信(互斥)
使用同步技术,使用锁对象
包子类:
public class BaoZi {
boolean flag = false;
String pi;
String xian;
public BaoZi() {
}
public BaoZi(boolean flag, String pi, String xian) {
this.flag = flag;
this.pi = pi;
this.xian = xian;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public String getPi() {
return pi;
}
public void setPi(String pi) {
this.pi = pi;
}
public String getXian() {
return xian;
}
public void setXian(String xian) {
this.xian = xian;
}
}
包子铺类:
public class Productor extends Thread{
//1.定一个包子变量
private BaoZi bz;
//2.带参数的构造方法,为这个包子变量赋值
public Productor(BaoZi bz) {
this.bz = bz;
}
@Override
public void run() {
int count = 0;
while (true) {
//同步技术
synchronized (bz) {
if (bz.flag == true) {
try {
bz.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//被唤醒后,生产包子
//交替生产两种包子
if(count % 2 == 0) {
//生产薄皮
bz.pi = "薄皮";
bz.xian = "三鲜馅";
}else {
bz.pi = "冰皮";
bz.xian = "牛肉大葱";
}
count++;
System.out.println("包子铺正在生产:" + bz.pi + bz.xian + "包子");
//生产需要3分钟
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//修改包子状态
bz.flag = true;
//唤醒吃货线程,让吃货线程吃包子
System.out.println("包子铺已经生产好" + bz.pi + bz.xian + "包子, 吃货可以开始吃");
}
}
}
}
顾客类:
public class Custmer extends Thread{
private BaoZi bz;
public Custmer(BaoZi bz) {
this.bz = bz;
}
//线程任务吃包子
@Override
public void run() {
while(true) {
synchronized (bz) {
if (bz.flag == true) {
} else {
try {
bz.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//被唤醒之后的动作:吃包子
System.out.println("吃货正在吃" + bz.pi + bz.xian + "包子");
bz.flag = false;
//吃货唤醒包子铺线程,生产包子
bz.notify();
System.out.println("吃货把" + bz.pi + bz.xian + "包子吃完了,包子铺开始生产包子");
System.out.println("============");
}
}
}
}
主方法:
public class DemoWAN3Main {
public static void main(String[] args) {
//创建包子对象
BaoZi bz = new BaoZi();
//创建包子铺线程,生产包子
new Productor(bz).start();
//创建吃货线程,开启吃包子
new Custmer(bz).start();
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。