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()的更多相关文章

  1. 使用ReentrantLock和Condition来代替内置锁和wait(),notify(),notifyAll()

    使用ReentrantLock可以替代内置锁,当使用内置锁的时候,我们可以使用wait() nitify()和notifyAll()来控制线程之间的协作,那么,当我们使用ReentrantLock的时 ...

  2. Java的锁机制--synchronsized关键字

    引言 高并发环境下,多线程可能需要同时访问一个资源,并交替执行非原子性的操作,很容易出现最终结果与期望值相违背的情况,或者直接引发程序错误. 举个简单示例,存在一个初始静态变量count=0,两个线程 ...

  3. Android-Java-synchronized同步锁机制&利与弊

    synchronized同步锁机制 定义锁

  4. [java多线程] - 锁机制&同步代码块&信号量

    在美眉图片下载demo中,我们可以看到多个线程在公用一些变量,这个时候难免会发生冲突.冲突并不可怕,可怕的是当多线程的情况下,你没法控制冲突.按照我的理解在java中实现同步的方式分为三种,分别是:同 ...

  5. java 多线程之wait(),notify,notifyAll(),yield()

    wait(),notify(),notifyAll()不属于Thread类,而是属于Object基础类,也就是说每个对像都有wait(),notify(),notifyAll()的功能.因为都个对像都 ...

  6. Java多线程之wait(),notify(),notifyAll()

    在多线程的情况下,因为同一进程的多个线程共享同一片存储空间,在带来方便的同一时候,也带来了訪问冲突这个严重的问题.Java语言提供了专门机制以解决这样的冲突,有效避免了同一个数据对象被多个线程同一时候 ...

  7. Java同步锁何时释放?

    在测试java多线程中有关 “生产者和消费者” 这个经典问题的时候,写代码测试的时候,思考到一些问题(所以还是要动手,实践才能储真知啊), synchronize 同步锁何时释放,何时获得?重新获得锁 ...

  8. java的锁机制

    一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在Java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个线 ...

  9. java的锁机制——synchronized

    一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个线 ...

随机推荐

  1. 详解ASP.NET Core API 的Get和Post请求使用方式

    上一篇文章帮助大家解决问题不彻底导致博友使用的时候还是遇到一些问题,欢迎一起讨论.所以下面重点详细讲解我们常用的Get和Post请求( 以.net core2.2的Http[Verb]为方向 ,推荐该 ...

  2. Discuz3.2与Java 项目整合单点登陆

    JAVA WEB项目与Discuz 论坛整合的详细步骤完全版目前未有看到,最近遇到有人在问,想到这个整个不是一时半会也解释不清楚.便把整个整合过程以及后续碰到的问题解决方案写下,以供参考. 原理 Di ...

  3. ATS 相关

    启动命令 /usr/local/CCTS/bin/trafficserver   start |stop | restart 清盘 /usr/local/CCTS/bin/traffic_server ...

  4. Java发送邮件 —— SpringBoot集成Java Mail

    用途:此文仅供,自己今后的小程序通过邮件,批量通知用户. 简单记录了一些发送基本邮件的操作. 项目(SpringBoot版本为2.1.2.RELEASE): 核心依赖(其他相关依赖,在其使用的地方具体 ...

  5. js打印html指定元素,解决动态获取的图片无法打印问题

    用js来调用浏览器的打印接口很容易,一两行代码就能搞定,但是有些数据是通过动态生成的,例如一些动态生成的二维码,有时候调用打印接口图片会无法显示 为了解决这个问题,建议使用下面这个库 下载:https ...

  6. 第 10 章 容器监控 - 078 - Docker 最常用的监控方案

    Docker 最常用的监控方案 当 Docker 部署规模逐步变大后,可视化监控容器环境的性能和健康状态将会变得越来越重要. Docker 自带的几个监控子命令: ps .top .stats 功能更 ...

  7. 下载 youtube 油管的视频

    以前也曾经用个工具下过,好像是浏览器插件. 但是到底是什么也记不起来了,删没删除,怎么删除的,全都没有记忆了. 唉,无论多么小的事,只有记到本子或者网络上,才能记得住啊. 所以,这回发现了 youtu ...

  8. 8.2 GOF设计模式一: 单实例模式 SingleTon

    GOF设计模式一: 单实例模式 SingleTon  整个美国,只有一个“现任美国总统”  比如,在学校,“老师”,有数百个:“校长”,只有一个  系统运行时,如何保证某个类只允许实例化一个对象 ...

  9. JSP 标准标签库JSTL

    JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能. JSTL支持通用的.结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签. 除了这些,它还提供 ...

  10. git reset 和 git revert 使用区别

    git reset 用于回退代码,但是git pull后会和远程分支保持一致,所以无法修改远程代码 git revert可以撤销代码,撤销后直接git push ,可以修改远程分支的代码