線程之“生產者消費者”
sleep():sleep來自Thread類,調用時線程睡眠但不釋放當前對象鎖(括號內加入睡眠時間,時間到後自然甦醒);
wait():wait來自Object類,調用線程睡眠釋放當前對象鎖定,進入等待線程池,出讓系統資源,其他線程可以佔用CPU資源,等待notify/notifyAll去對它進行喚醒後重新進入就緒態(括號內亦可加時間,與sleep方法類似);
synchronized:線程同步鎖,當它用來修飾一個方法或者一個代碼塊的時候,能夠保證在同一時刻最多隻有一個線程執行該段代碼。
notify():隨機喚醒等待池線程,線程優先級越高,分配資源越多,喚醒概率越大;
notifyAll():喚醒所有wait()的線程。
其中sleep需要捕獲異常,wait,notify/notifyAll不需要。
本次實驗
生產者:做饅頭,每做一個休息0.5s,當饅頭大於10個時停止生產。
消費者:吃饅頭,每吃一個休息1s,當饅頭小於等於2個時喚醒生產者繼續生產。
package Thread;
//生產者
public class Producer extends Thread {
private Container container;
public Producer(Container container){
super();
setName("生產者");
this.setContainer(container);
}
public Container getContainer() {
return container;
}
public void setContainer(Container container) {
this.container = container;
}
public void run(){
while(true){
container.add();//生產饅頭
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package Thread;
//消費者
public class Consumer extends Thread {
private Container container;
public Consumer(Container container){
super();
setName("消費者");
this.setContainer(container);
}
public Container getContainer() {
return container;
}
public void setContainer(Container container) {
this.container = container;
}
public void run(){
while(true){
container.sub();//吃饅頭
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package Thread;
//容器,把 **數量的判斷和增減** 抽取出來使用sychronized進行同步
public class Container extends Thread {
public int size = 0;
/*public int count = 0;*/
public synchronized void add(){
String name = Thread.currentThread().getName();
//數量判斷
if(size>=10){
System.out.println(name + "說:裝不下啦!!我先休息一下!");
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else {
//數量增減
System.out.println(name +"正在做饅頭!"+ ++size);
if(size>5){
System.out.println("來吃饅頭啦!!");
}
this.notify();
}
}
public synchronized void sub(){
String name = Thread.currentThread().getName();
//數量判斷
if(size<=0){
System.out.println(name +"說:沒饅頭啦");
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else {
//數量增減
System.out.println(name + "吃饅頭!!"+ --size);
/*System.out.println(name + "我已經吃了"+ ++count +"個啦");*/
/*if(count>=10){
System.out.println(name +"吃不下了,休息一下!");
try {
Thread.sleep(5000);
count=0;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.notify();
}*/
//數量判斷
if(size<=2){
System.out.println(name +"大吼:快來做饅頭!!");
this.notify();
}
}
}
}
package Thread;
public class Test {
public static void main(String[] args) {
Container container = new Container();
Producer producer = new Producer(container);
Consumer consumer = new Consumer(container);
producer.start();
consumer.start();
}
}