/*
* 進(jìn)程通信
* 定義:一個(gè)線程完了任務(wù)以后,通知另外一個(gè)線程去完成其他的任務(wù),這個(gè)通知以及通知的內(nèi)容就稱為線程通信
* 參與者: 生產(chǎn)者\(yùn)消費(fèi)者\(yùn)共享對(duì)象
* 實(shí)現(xiàn)方法:
* wait() 等待 如果一個(gè)線程調(diào)用了wait方法,就會(huì)進(jìn)入等待狀態(tài),直到被其他線程notify才繼續(xù)運(yùn)行;
* notify() 喚醒線程池中等待的其中一個(gè)線程
*? notifyAll()
*
* 注意:
* 1. wait和notify是屬于Object對(duì)象:
* 2. wait和notify必須在同步代碼塊和同步函數(shù)中才能執(zhí)行
* 3. wait和notiry必須要有鎖對(duì)象調(diào)用才能正常使用:
* 4. 生產(chǎn)者和消費(fèi)者只共享一個(gè)對(duì)象,因此不會(huì)出現(xiàn)死鎖的問(wèn)題:
*? 5. wait和notify方法必須用鎖對(duì)象來(lái)調(diào)用,否則會(huì)報(bào)錯(cuò).
*
* wait()和notify()方法詳解
* wait() 當(dāng)一個(gè)線程調(diào)用了wait()方法,就會(huì)放棄CUP執(zhí)行權(quán)進(jìn)入到一個(gè)以鎖對(duì)象為標(biāo)識(shí)符的線程池中,作用是進(jìn)入線程池,但是不會(huì)喚醒其他
* notify() 當(dāng)一個(gè)線程調(diào)用了notify方法,那么就會(huì)喚醒線程池中的某個(gè)線程(等待中),作用是讓出CPU執(zhí)行權(quán),但是不會(huì)進(jìn)入線程池;
*
*/
//生產(chǎn)者和消費(fèi)者的共享對(duì)象,只有一個(gè),不會(huì)出現(xiàn)死鎖
class Product
{
String name; //產(chǎn)品名稱
double price; //產(chǎn)品價(jià)格
boolean isProducted = false; //產(chǎn)品是否生產(chǎn)出來(lái)的標(biāo)記
}
//生產(chǎn)者
class Producer extends Thread
{
Product p;
//構(gòu)造函數(shù),獲取共享對(duì)象
public Producer(Product p)
{
super();
this.p = p;
}
@Override
//重寫run方法
public void run() {
// TODO Auto-generated method stub
super.run();
int i =0;
while(true)
{
//共享代碼塊,用同一個(gè)對(duì)象來(lái)上鎖,同一把鎖
synchronized(p)
{
//判斷是否被生產(chǎn)出來(lái)
if(p.isProducted)
{
p.notify();
}else{
//未被生產(chǎn)出來(lái),開(kāi)始生產(chǎn)
if(i%2 == 0)
{
p.name = "蘋果";
p.price = 6.5;
}else{
p.name = "香蕉";
p.price = 2.0;
}
//生產(chǎn)出來(lái),進(jìn)入等待狀態(tài),等待被消費(fèi)
p.isProducted = true;
System.out.println(p.name + "已經(jīng)被生產(chǎn)出來(lái),等待消費(fèi)!" );
i++;
p.notify();
try {
p.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
//消費(fèi)者
class Consumer extends Thread
{
Product p;
//構(gòu)造函數(shù),獲取同一個(gè)對(duì)象來(lái)維護(hù)
public Consumer(Product p){
super();
this.p = p;
}
//重寫run方法
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
int i = 0;
while(true){
synchronized(p){
//判斷是否被生產(chǎn)s
if(p.isProducted){
System.out.println(p.name + "已經(jīng)被消費(fèi),價(jià)格是:" + p.price);
p.isProducted = false;
//通知繼續(xù)生產(chǎn)
p.notify();
}else{
//還未被生產(chǎn),等待生產(chǎn)出來(lái);
try {
p.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
public class Demo7 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Product p = new Product();
Producer pro = new Producer(p);
Consumer con = new Consumer(p);
pro.start();
con.start();
}
}