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()的更多相关文章
- 使用ReentrantLock和Condition来代替内置锁和wait(),notify(),notifyAll()
使用ReentrantLock可以替代内置锁,当使用内置锁的时候,我们可以使用wait() nitify()和notifyAll()来控制线程之间的协作,那么,当我们使用ReentrantLock的时 ...
- Java的锁机制--synchronsized关键字
引言 高并发环境下,多线程可能需要同时访问一个资源,并交替执行非原子性的操作,很容易出现最终结果与期望值相违背的情况,或者直接引发程序错误. 举个简单示例,存在一个初始静态变量count=0,两个线程 ...
- Android-Java-synchronized同步锁机制&利与弊
synchronized同步锁机制 定义锁
- [java多线程] - 锁机制&同步代码块&信号量
在美眉图片下载demo中,我们可以看到多个线程在公用一些变量,这个时候难免会发生冲突.冲突并不可怕,可怕的是当多线程的情况下,你没法控制冲突.按照我的理解在java中实现同步的方式分为三种,分别是:同 ...
- java 多线程之wait(),notify,notifyAll(),yield()
wait(),notify(),notifyAll()不属于Thread类,而是属于Object基础类,也就是说每个对像都有wait(),notify(),notifyAll()的功能.因为都个对像都 ...
- Java多线程之wait(),notify(),notifyAll()
在多线程的情况下,因为同一进程的多个线程共享同一片存储空间,在带来方便的同一时候,也带来了訪问冲突这个严重的问题.Java语言提供了专门机制以解决这样的冲突,有效避免了同一个数据对象被多个线程同一时候 ...
- Java同步锁何时释放?
在测试java多线程中有关 “生产者和消费者” 这个经典问题的时候,写代码测试的时候,思考到一些问题(所以还是要动手,实践才能储真知啊), synchronize 同步锁何时释放,何时获得?重新获得锁 ...
- java的锁机制
一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在Java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个线 ...
- java的锁机制——synchronized
一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个线 ...
随机推荐
- Python模块 2
collections模块 在内置数据类型(dict.list.set.tuple)的基础上,collections模块还提供了几个额外的数据类型: 1.namedtuple: 生成可以使用名字来访问 ...
- Django模板语言
day66 2018-05-08 1. 内容回顾 1. 模板系统(字符串替换) 1. 语法 1. 变量相关: {{ name }},{{name|length}},{{name|default:&qu ...
- CF 528D. Fuzzy Search NTT
CF 528D. Fuzzy Search NTT 题目大意 给出文本串S和模式串T和k,S,T为DNA序列(只含ATGC).对于S中的每个位置\(i\),只要中[i-k,i+k]有一个位置匹配了字符 ...
- 前端——Bootstrap
Bootstrap介绍 Bootstrap是Twitter开源的基于HTML.CSS.JavaScript的前端框架. 它是为实现快速开发Web应用程序而设计的一套前端工具包. 以前自己写的html的 ...
- error_Could not load file or assembly
原文链接 Could you be missing the loaded assembly from your configuration file? Ensure you have somethin ...
- jquery.validator 手机号验证
1.在input中加上mobile="true",maxlength="11" <label class="w170 control-label ...
- git push时报错:Updates were rejected because the tip of your current branch is behind
出现这样的问题是由于:自己当前版本低于远程仓库版本 有如下几种解决方法: 1.使用强制push的方法: git push -u origin master -f 这样会使远程修改丢失,一般是不可取的, ...
- mysql 插入中文字段报错 "Incorrect string value: '\\xE6\\xB5\\x8B\\xE8\\xAF\\x95...' for column 'title' at row 1"
1. 查看一个 database 或一个 table 的编码show create database mytestdb;show create table testapp_article; mysql ...
- Vue-admin工作整理(十一):Vuex-动态注册模块
概述: 动态注册模块分为两种,一种是在根state下注册一个模块,一种是在模块下再自动注册一个模块 第一种:根state下动态注册模块: 思路:通过store来实现,this.$store来获取当前的 ...
- 如何增加亚马逊listing多个类目节点
流量是电商销售的必要因素,可以说,任何成功的电商平台都离不开流量.亚马逊listing优化做得好,不仅能提高产品的曝光率,还能提升转换率,而好的类目可以吸引大的流量.帮你快速爬升. 首先我们来了解一下 ...