標籤:wait()與notify()
JAVA線程互動
線程的運行都是獨立的,但是存在多個線程需要同時訪問共用的資源時,需要用到線程的同步(synchronized),就相當於在共用的對象資源上加了一把鎖,每次只能一個線程獲得對象鎖。最簡
單的例子:如賣電影票,幾個視窗(線程)同時對電影票進行銷售,彼此線程都是互斥的,每次只能一個線程去訪問電影票(這個對象)。但是也存在一種生產者-消費者的流程,這時需要用到線程的互動(wait()與notify()/notifyAll(),等待-喚醒),比如寫個生產包子與賣包子的例子,每次生產包子到100個後就通知去賣包子,當賣包子到0時,就通知生產包子。
1:定義一個包子物件,
public class Manager{
private int count;//包子的數量
private String name;//包子的名稱
public int maxcount=100;//包子的最大數量
public boolean k;//用於判斷包子是否還有,預設是FALSE,用true代表包子有,通知消費,用false代表包子沒有,通知生產。
//建構函式
public Manager(String name,int count){
this.name=name;
this.count=count;
}
public int getCount(){
return this.count;
}
public int setCount(int y){
return this.count+=y;
}
}
//定義一個生產包子的線程
public class Producer implements Runnable{
private Manager ma;//定義一個共用對象
public Producer(Manager ma){
this.ma=ma;//保證傳遞進來的是同一個共用對象
}
public void run(){
//因為不知道是生產線程先運行還是消費線程先運行,所以必須先判斷
while(true){
//無限迴圈,保證賣完就生產
synchronized(ma){//傳遞對象鎖
if(ma.k==true){//狀態為true,代表包子已經有了,就等待,通知消費。
ma.wait();//這裡需要添加try-catch,一旦包子數量有,則需要消費線程去 notify(),當前線程就等待喚醒。
}
if(ma.getCount<100){//當包子數量少於100個,就生產
ma.setCount(5);
System.out.println("生產了5個,總量為;"+ma.getCount());
}
ma.k=true;//包子數量大於100個了,所以改變狀態
ma.notify();//通知消費者去消費
}
}
}
}
//定義一個消費線程
public class Custer implements Runnable{
private Manager ma;
public Custer(Manager ma){
this.ma=ma;
}
public void run(){
while(true){
synchronized(ma){
if(ma.k==false){
ma.wait();//當包子的狀態為false,代表消費需要等待生產。
}
if(ma.getCount()>0){
ma.setCount(-2);
System.out.println("包子已經消費2個,剩下:"+ma.getCount());
}
ma.k=false;//包子已經消費完了,需要生產。
ma.notify();
}
}
}
}
//定義一個主線程類,開始運行
public class Testdemo{
public static void main(String[] args){
Manager ma=new Manager("包子",0);//定義一個包子物件
Producer p=new Producer(ma);//建立生產對象
Custer c=new Custer(ma); //建立消費對象
Thread t1=new Thread(p);//建立生產線程對象
Thread t2=new Thread(c); //建立消費線程對象
t1.start();//啟動生產線程
t2.start(); //啟動消費線程
}
}
本文出自 “JAVA學習記錄” 部落格,請務必保留此出處http://20150523.blog.51cto.com/10261028/1654647
JAVA線程互動