java notify 指定_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();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值