1 .
需求:如果生产不到6个面包,可继续生产,当面包个数大于0,可以进行消费.但是如果面包的数量为6个时,则停止生产.如果面包个数为0个时, 则停止消费.
2 .
在这里,需要一个面包类,有面包的属性和一些方法.
需要有消费者类,
需要有生产者类,
需要有超市类,作为共享资源类,(因为消费者和生产者不能直接打交道),
还需要有个测试类.
3 .
面包类:
package com.qf.demo4;
public class Bread {
private String brand;
private int price;
public Bread(String brand, int price) {
super();
this.brand = brand;
this.price = price;
}
public Bread() {
super();
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "Bread [brand=" + brand + ", price=" + price + "]";
}
}
生产者类:
package com.qf.demo4;
public class Facotory implements Runnable{
Markt markt;
public Facotory(Markt markt) {
this.markt = markt;
}
public void run() {
for (int i = 1; i <= 100; i++) {
markt.product(new Bread("二狗"+i, i));
}
}
}
消费者类:
package com.qf.demo4;
public class Custmer implements Runnable{
Markt markt;
public Custmer(Markt markt) {
this.markt = markt;
}
public void run() {
for (int i = 0; i < 100; i++) {
markt.sale();
}
}
}
超市类(资源类):
package com.qf.demo4;
public class Markt {
Bread[] breads = new Bread[6];
int index = -1;// 标志 一个面包也没有
// 生产
public synchronized void product(Bread bread){
// 面包是6 的话就停止生产
if(index==5){
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 想要向数组中添加一个面包
index++;
breads[index] = bread;
System.out.println("生产者生产了一个面包"+bread);
this.notify();
// 不足留个 就生产
}
// 消费
public synchronized void sale(){
// 面包个数大于0 的时候就 消费
if(index==-1){
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("消费者消费了一个面包"+breads[index]);
index--;
this.notify();
// 不足的0 的时候 就等待
}
}
测试类:
package com.qf.demo4;
/**
* 生产者消费者模型
* 1 产品
* 2 超市(代理)
* 3 生产者
* 4 消费者
* 线程间通信
*
* @author Administrator
*
*/
public class Test {
public static void main(String[] args) {
Markt markt= new Markt();
Facotory facotory = new Facotory(markt);
Custmer custmer = new Custmer(markt);
Thread thread = new Thread(facotory);
Thread thread2 = new Thread(custmer);
thread.start();
thread2.start();
}
}
总结:这和上面的文章提到的男朋友存钱,女朋友取钱交换着操作是一个道理,只不过是着可以连续操作好几次,例如可以连续生产或者连续消费,而上面提到的则是存钱之后立马要取钱,然后在存钱.
接口回调::
1 . 回调:就是A类中调用B类中的某个方法C,然后B类中反过来调用A类中的方法D,D这个方法就叫回调方法
2 . 接口回调,回调的是接口的方法.这个方法就是回调方法
3 . 首先定义一个接口
package com.qf.demo6;
public interface Phone {
public void getResult(String result);
}
其次,创建二狗类,要提问问题,但是只能通过皮皮虾类接收问题,皮皮虾类接收问题之后,皮皮虾类里面接口对象调用二狗类中的回调方法(也就是phone.getResult()),输出信息
二狗类:
package com.qf.demo6;
/**
* 接口回调
* 二狗类中 想要数据,但是二狗类不能直接得到结果, 皮皮虾类中有结果
* 通过一个接口将数据回传
*
* 想要数据的类创建接口对象,并且重写抽象方法, 将接口对象 传递给有数据的类
*
* 有数据的类 通过接口对象 调用 重写的接口的方法
*
*
*
* @author Administrator
*
*/
public class TwoDog {
// 二狗要问问题
PiPiXia piPiXia = new PiPiXia();
public void askQuestion(){
piPiXia.accepQuestion("1+1=?",new Phone() {
public void getResult(String result) {// "2"
System.out.println(result);
}
});
}
// public void getResult(String result){
// System.out.println(result);
// }
}
皮皮虾类:
package com.qf.demo6;
/**
* 接口 当做 一个 传输数据工具
*
* @author Administrator
*
*/
public class PiPiXia {
public void accepQuestion(String question, final Phone phone){
System.out.println("我要睡觉呢,睡醒了再告诉你");
new Thread(new Runnable() {
public void run() {
System.out.println("一年以后, 皮皮虾睡醒了");
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("一年以后, 皮皮虾睡醒了");
phone.getResult("2");
}
}).start();
}
}
测试类:
package com.qf.demo6;
/**
* 二狗 1+1=?
* 给皮皮虾打电话
* 皮皮虾说我睡会觉, 睡醒了再告诉你
* 一年以后 皮皮虾属性了, 就想起来 二狗问的问题
* 想办法告诉二狗 结果是 2
*
*/
public class Test {
public static void main(String[] args) {
TwoDog twoDog = new TwoDog();
twoDog.askQuestion();
}
}