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里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个线 ...
随机推荐
- objectarx 读取外部DWG图到当前图形
void CTrimeDraw::MyReadDwgFile(CString str){ AcDbDatabase pExternalDb(Adesk::kFalse); // 外部图形数据库 if ...
- Bytom Kit开发辅助工具介绍
Bytom Kit是一款为了帮助开发者更简单地理解Bytom的开发辅助工具,集合了校验.标注.解码.测试水龙头等功能. 该工具用python语言封装了一套比原的API和7个工具方法,如果有开发需求可以 ...
- JS的Date对象、Math、包装类
Date对象 在JS使用Date对象来表示时间 当前时间 var d = new Date(); 指定时间 格式:月/日/年 时:分:秒 var e = new Date("02/16/ ...
- Python中不尽如人意的断言Assertion
Python Assert 为何不尽如人意 Python中的断言用起来非常简单,你可以在assert后面跟上任意判断条件,如果断言失败则会抛出异常. >>> assert 1 + 1 ...
- centOS 及 ubuntu 下载地址记录
CentOS下载地址: http://isoredirect.centos.org/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-1611.iso : ubu ...
- flask No such command "init-db".
在Daily目录下,使用cmd窗口执行,不要使用IDE的命令行 set FLASK_APP=DLY set FLASK_ENV=development flask init_app
- 爬坑之路---Google map
google.maps.event.adddDomListen(window, 'load', callback);当文档流中所有的dom加载完成后,执行回调函数,可以不用在script中使用defe ...
- Collectors类中的静态工厂方法
工厂方法 返回类型 用于 toList List<T> 把流中的所有数据元素收集到List集合中. stream.collect(toList()); toSet Set<T> ...
- 技巧 筛1~n的所有因子
从 i : 1~n, 是i的倍数, 则计入该数 复杂度 n*(1/1+1/2+1/3+...1/n)=nlogn ll d[N]; // 计每个数的因子数 set<ll> s[N]; // ...
- (5)TCP和UDP协议
TCP(Transmission Control Protocol)可靠的.面向连接的协议(eg:打电话).传输效率低全双工通信(发送缓存&接收缓存).面向字节流.使用TCP的应用:Web浏览 ...