JAVA同步锁机制 wait() notify() notifyAll()

Posted yanhuang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA同步锁机制 wait() notify() notifyAll()相关的知识,希望对你有一定的参考价值。

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()的主要内容,如果未能解决你的问题,请参考以下文章

java锁之wait,notify(wait会释放锁,notify仅仅只是通知,不释放锁)

Java并发编程之二彻底理解Java的wait和Notify机制

为啥wait,notify和notifyAll必须在同步块或同步方法中调

java基础——线程通信机制,生产者消费者

(二)线程状态、wait/notify

java并发之线程同步(synchronized和锁机制)