线程通信:
1.含义:
我们可以把线程通信比喻成生产者和消费者之间关系,生产者将生产商品放到库存里面,消费者消费库存内的商品,生产者和消费者共享库存资源,当库存内的商品不足时,消费者需要等待生产者生产之后才能使用。多个线程之间需要建立一个共享的资源池子,所有线程在这个池子来进行资源的传递。
2.java解决线程通信之间的通信问题的方法:
**wait():**表示线程一直等待,直到其他线程通知,与Sleep不同,会释放锁
**wait(long timeout):**指定等待的毫秒数
**notify():**唤醒处于等待状态的线程
**notifyALL():**唤醒同一对象上所有调用wait()方法的线程,优先级高的有限调用
2.1代码案例
//管程法:测试消费和生产者,利用缓冲区解决
public class TestXianChencommunita {
public static void main(String[] args) {
SynCntainer cntainer=new SynCntainer();
new Productor(cntainer).start();
new Costomer(cntainer).start();
}
}
//生产者类
class Productor extends Thread{
//建立资源池子
SynCntainer cntainer;
//构造器初始化资源池子,实例化资源类
public Productor(SynCntainer cntainer) {
this.cntainer=cntainer;
}
//生产者需要一个生产方法
@Override
public void run() {
for (int i = 1; i < 50; i++) {
cntainer.push(new Product(i));//将生产的商品放入资源池子
System.out.println("生产者生产了"+i+"个产品");
}
}
}
//消费者
class Costomer extends Thread{
//建立资源池子,实例化资源类
SynCntainer cntainer;
//构造器初始化资源池子
public Costomer(SynCntainer cntainer) {
this.cntainer=cntainer;
}
//需要一个消费的方法
@Override
public void run() {
for (int i = 1; i < 50; i++) {
System.out.println("消费者消费了--->"+cntainer.pop().id+"个产品");//调用资源实例内方法消费商品
}
}
}
//商品类别
class Product {
int id;//产品编码
public Product(int id){
this.id=id;
}
}
//资源池子:缓冲器,容器
class SynCntainer {
//需要一个容器。设置资源池子的容量
Product[] products=new Product[5];
//容器计数器,计算资源池子内的资源数量
int count=0;
//1.需要生产者放入产品
public synchronized void push(Product product){
if(count==products.length) {//当资源池子有库存时
//如果容器满了,需要等待消费者
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//如果没有满,我们可以丢入产品
products[count]=product;
count++;
//可以通知消费者消费了
this.notifyAll();
}
//2.消费者消费商品
public synchronized Product pop(){
//判断是否消费
if(count==0){//当资源池子没有库存时
//等待生产者生产,消费者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//消费者可以消费
count--;
Product product=products[count];//更新资源池子内商品数量
//通知生产者生产
this.notifyAll();
return product;//返回最新的资源数量
}
}
2.2运行结果