1. 程式人生 > >JAVA同步鎖機制 wait() notify() notifyAll()

JAVA同步鎖機制 wait() notify() notifyAll()

使用 stack .get 不同 string java rri main cer

wait() notify() notifyAll() 這3個方法用於協調多個線程對共享數據的存取,所以必須在synchronized語句塊中使用。

  wait() 必須在synchronized函數或者代碼塊裏面,wait()會讓已經獲得synchronized函數或者代碼塊控制權的Thread暫時休息,並且喪失控制權,這個時候,由於該現象喪失控制權並且進入等待,其他線程就能取得控制權,並且在適當情況下調用notifyAll() 來喚醒wait()的線程。需要註意的是,被喚醒的線程由於已經喪失控制權,其他的線程可以乘虛而入,所以wait()的使用,必須在2個以上的線程,而且必須在不同的條件下喚醒wait()中的線程。

  notifyAll()並不是讓當前線程馬上讓出控制權,而只是讓其他wait()當中的線程喚醒而已,所以盡管我喚醒你,可你必須還是要等我用完倉庫才能進來。

  舉例說明:生產者和消費者共享的同步機制。

  ProductList 是一個產品倉庫,當倉庫滿的時候,生產者線程需要wait(),從而放棄對產品倉庫的控制,這個時候消費者線程就可以進來且取得倉庫的控制權,一旦消費者消費了產品,倉庫就不再是滿,這時候消費者線程就有notifyAll() 生產者線程讓等待的生產者線程喚醒,但是生產者不會馬上進行生產,需要等消費者線程結束操作,才能重新獲得倉庫的控制權,再進行生產。

//產品類
public class Product {
int id;
private String producedBy = "N/A";
private String consumedBy = "N/A";

//指定生產者名字
Product(String producedBy){
this.producedBy = producedBy;
}

//指定消費者名字
public void consume(String consumedBy){
this.consumedBy = consumedBy;
}

public String toString(){
return "產品,生產者 = "+producedBy +",消費者 = "+consumedBy;
}
public String getProducedBy(){
return producedBy;
}
public void setProducedBy(String producedBy) {
this.producedBy = producedBy;
}

public String getConsumedBy(){
return consumedBy;
}
public void setConsumedBy(String consumedBy) {
this.consumedBy = consumedBy;
}
}



//倉庫類
public class ProductList {
int index = 0;
Product[] productlist = new Product[6];

//生產者存放產品
public synchronized void push(Product product){
//倉庫滿了
while (index == productlist.length){
try {
System.out.println(" "+product.getProducedBy() + "is waiting.");
wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
//notifyAll()之後,還是會繼續執行直到完成
productlist[index] = product;
index++;
System.out.println(index+" " + product.getProducedBy()+"生產了:"+product);
notifyAll();
System.out.println(" "+product.getProducedBy()+"send a notifyAll().");
}


//消費者 取出產品
public synchronized Product pop(String consumeName){
while (index ==0){//倉庫空了
try {
System.out.println(" "+consumeName+"is waiting.");
wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}

//一樣會繼續執行到完成
index--;
Product product = productlist[index];
product.consume(consumeName);
System.out.println(index+""+product.getConsumedBy()+" 消費了:"+product);
notifyAll();
return product;
}
}

//生產者類
public class Producer implements Runnable {
String name;
ProductList ps = null;
Producer(ProductList ps,String name){
this.ps = ps;
this.name = name;
}

public void run(){
while (true){
Product product = new Product(name);
ps.push(product);
try {
Thread.sleep((int)(Math.random() * 200));
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}

//消費者類
public class Consumer implements  Runnable{
String name;
ProductList ps = null;

Consumer(ProductList ps ,String name){
this.ps = ps;
this.name = name;
}

@Override
public void run() {
while (true){
ps.pop(name);
try {
Thread.sleep(((int)Math.random() * 1000));
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}


//測試類

public class Test {
public static void main(String[] args) {
ProductList ps = new ProductList();
Producer px = new Producer(ps,"生產者X");
Producer py = new Producer(ps,"生產者Y");

Consumer ca = new Consumer(ps,"消費者A");
Consumer cb = new Consumer(ps,"消費者B");
Consumer cc = new Consumer(ps,"消費者C");

new Thread(px).start();
new Thread(py).start();
new Thread(ca).start();
new Thread(cb).start();
new Thread(cc).start();
}

}
 



JAVA同步鎖機制 wait() notify() notifyAll()