在JDK的官方的wait()方法的注释中明确表示线程可能被“虚假唤醒“,JDK也明确推荐使用while来判断状态信息。那么这种情况的发生的可能性有多大呢?

使用生产者消费者模型来说明,伪唤醒造成的后果是本来未被唤醒的线程被唤醒了,那么就破坏了生产者消费者中的判断条件,也就是例子中的while条件number == 0或者number == 1。最终导致的结果就死0和1不能交替出现。

JDK的两种同步方案均可能出现这种伪唤醒的问题(API说明明确表示会出现这种现象),这两种组合是synchronized+wait+notify和ReentrantLock+await+signal。下面的例子中,如果把while换成if,那么就0、1就不能交替出现,反制则会,例子中是100个线程进行增加,100个线程进行减少。

在Java并发编程书上面引用了Thinking In Java的一句话说,大概意思是:任何并发编程都是通过加锁来解决。其实JDK并发编程也是通过加锁解决,每个对象都有一个对象锁,并且有一个与这个锁相关的队列,来实现并发编程。区别在于加锁的粒度问题,读读可以并发(在读远大于写的场景下比较合适),其他三种情况不能并发。而关系型数据库也是利用这一思想,只不过做得更加彻底,除了写写不能并发,其他三种情况都能并发,这得益于MVCC模型。

public class Resource {

public int number = 0;

public synchronized void add() {

while (number == 1) {

try {

wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

number++;

System.err.println(number + "-" + Thread.currentThread().getId());

notifyAll();

}

public synchronized void minus() {

while (number == 0) {

try {

wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

number--;

System.err.println(number + "-" + Thread.currentThread().getId());

notifyAll();

}

public static class AddThread implements Runnable {

private Resource resource;

public AddThread(Resource resource) {

this.resource = resource;

}

@Override

public void run() {

for (;;) resource.add();

}

}

public static class MinusThread implements Runnable {

private Resource resource;

public MinusThread(Resource resource) {

this.resource = resource;

}

@Override

public void run() {

for (;;) resource.minus();

}

}

public static void main(String[] args) {

Resource resource = new Resource();

for (int i = 0; i < 100; i++) {

new Thread(new AddThread(resource)).start();

new Thread(new MinusThread(resource)).start();

}

}

}

public class ResourceLock {

private int number = 0;

private final ReentrantLock lock = new ReentrantLock();

private final Condition condition = lock.newCondition();

public int getNumber() {

return this.number;

}

public void increase() {

lock.lock();

try {

while (number == 1) {

condition.await();

}

number++;

System.err.println(number + "-" + Thread.currentThread().getId());

condition.signalAll();

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

if (lock.isHeldByCurrentThread()) {

lock.unlock();

}

}

}

public void decrease() {

lock.lock();

try {

while (number == 0) {

condition.await();

}

number--;

System.err.println(number + "-" + Thread.currentThread().getId());

condition.signalAll();

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

if (lock.isHeldByCurrentThread()) {

lock.unlock();

}

}

}

static class IncreaseThread implements Runnable {

private ResourceLock resource;

public IncreaseThread(ResourceLock resource) {

this.resource = resource;

}

@Override

public void run() {

for (;;) resource.increase();

}

}

static class DecreaseThread implements Runnable {

private ResourceLock resource;

public DecreaseThread(ResourceLock resource) {

this.resource = resource;

}

@Override

public void run() {

for (;;) resource.decrease();

}

}

public static void main(String[] args) throws Exception {

ResourceLock resource = new ResourceLock();

ExecutorService es = Executors.newFixedThreadPool(5);

for (int i = 0; i < 100; i++) {

es.submit(new IncreaseThread(resource));

es.submit(new DecreaseThread(resource));

}

}

}

多线程 - 线程通信 suspend-resume wait-notify park-unpark 伪唤醒

线程通信(如 线程执行先后顺序,获取某个线程执行的结果等)有多种方式: 文件共享 线程1 --写入--> 文件 < --读取-- 线程2 网络共享 变量共享 线程1 --写入--> ...

Java多线程系列--&OpenCurlyDoubleQuote;基础篇”05之 线程等待与唤醒

概要 本章,会对线程等待/唤醒方法进行介绍.涉及到的内容包括:1. wait(), notify(), notifyAll()等方法介绍2. wait()和notify()3. wait(long t ...

java 多线程—— 线程等待与唤醒

java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...

Java多线程(五)——线程等待与唤醒

一.wait().notify().notifyAll()等方法介绍 在Object.java中,定义了wait(), notify()和notifyAll()等接口.wait()的作用是让当前线程进 ...

java - 线程等待与唤醒

Java多线程系列--“基础篇”05之 线程等待与唤醒 概要 本章,会对线程等待/唤醒方法进行介绍.涉及到的内容包括:1. wait(), notify(), notifyAll()等方法介绍2. w ...

java 多线程系列基础篇(五)之线程等待与唤醒

1.wait(), notify(), notifyAll()等方法介绍 在Object.java中,定义了wait(), notify()和notifyAll()等接口.wait()的作用是让当前线 ...

Java:谈谈控制线程的几种办法

目录 Java:谈谈控制线程的几种办法 join() sleep() 守护线程 主要方法 需要注意 优先级 弃用三兄弟 stop() resume suspend 中断三兄弟 interrupt() ...

jdk线程池主要原理

本文转自:http://blog.csdn.net/linchengzhi/article/details/7567397 正常创建一个线程的时候,我们是这样的:new thread(Runnable ...

jdk线程常见面试题

请编写一个多线程程序,实现两个线程,其中一个线程完成对某个对象int成员变量的增加操作,即每次加1,另一个线程完成对该对象成员变量的减操作,即每次减1,同时要保证该变量的值不会小于0,不会大于1,该变 ...

随机推荐

corefile 设置

程序运行的过程中,可能会因为一些隐藏的bug导致崩溃,为了在出问题时,及时记录所在环境的情况,所以要设置core文件的产生.其实其本质就是把进程的内存保存到文件中去. 1.core文件的生成开关和大小 ...

HDU 1253 胜利大逃亡

Problem Description Ignatius被魔王抓走了,有一天魔王出差去了,这可是Ignatius逃亡的好机会. 魔王住在一个城堡里,城堡是一个A*B*C的立方体,可以被表示成A个B*C ...

Redis实践操作之—— keyspace notification(键空间通知)

一.需求分析: 设置了生存时间的Key,在过期时能不能有所提示? 如果能对过期Key有个监听,如何对过期Key进行一个回调处理? 如何使用 Redis 来实现定时任务? 二.序言: 本文所说的定时任务 ...

Android 框架简介--Java环境&lpar;转&rpar;

==========================上=========================== 这里简单的介绍了Android的java环境基础,在后面一节中会结合具体的实例来理解这一节 ...

开源安卓播放器:Dolphin Player 简单分析

Dolphin播放器(Dolphin Player)是一款开源的音频和视频播放器,它支持大多数的音频和视频文件模式,也支持大部分的字幕文件格式.它是基于ffmpeg的. 项目主页:http://cod ...

PHP学习笔记1&period;2——预定义变量参考

预定义变量和用户自定义变量在使用上没有区别,大多数预定义变量的执行结果都是服务器的相关信息(如:版本号.路径.错误参数等),所以我们很少将其用于网站前台开发,如果被别有用心得人知道了后,会严重威胁服务 ...

相机标定 matlab opencv ROS三种方法标定步骤(3)

三 ,  ROS 环境下 如何进行相机标定 刚开始做到的时候遇到一些问题没有记录下来,现在回头写的时候都是没有错误的结果了,首先使用ROS标定相机, 要知道如何查看节点之间的流程图  rosrun r ...

获取生日对应星座的PHP函数

PHP 获取指定日期对应的星座名称 /** * 获取指定日期对应星座 * * @param integer $month 月份 1-12 * @param integer $day 日期 1-31 * ...

Redis的key过期处理策略

Redis中有三种处理策略:定时删除.惰性删除和定期删除. 定时删除:在设置键的过期时间的时候创建一个定时器,当过期时间到的时候立马执行删除操作.不过这种处理方式是即时的,不管这个时间内有多少过期键, ...

&lbrack;Sikuli&rsqb; Sikuli安装

http://blog.csdn.net/defectfinder/article/details/49819215 1.下载 sikulixsetup-1.1.0.jar (md5, sig) ht ...

java伪唤醒,谈谈JDK线程的伪唤醒相关推荐

  1. 谈谈JDK线程的伪唤醒

    在JDK的官方的wait()方法的注释中明确表示线程可能被"虚假唤醒",JDK也明确推荐使用while来判断状态信息.那么这种情况的发生的可能性有多大呢? 使用生产者消费者模型来说 ...

  2. 谈谈css中的伪类和伪元素,谈谈css中的伪类和伪元素

    熟习前台的人都会听过css的伪类与伪元素,然而大多数的人都会将这两者混淆.本文从解析伪类与伪元素的含义出发,区分这两者的区别,并且列出大部分伪类与伪元素的具体用法. css选择器 css选择除了我们常 ...

  3. java队列等待唤醒_Java深入学习29:线程等待和唤醒的两个方案

    Java深入学习29:线程等待和唤醒的两个方案 模拟场景 一个门店,有一个店员,有消费者来消费商品(每次消费1件商品),有仓库人员来添加(生产)商品(每次生产1件商品),并假设库存上限是2. 基础代码 ...

  4. java线程挂起唤醒_java线程技术6_线程的挂起和唤醒[转]

    转自:http://blog.chinaunix.net/uid-122937-id-215913.html 1. 线程的挂起和唤醒 挂起实际上是让线程进入"非可执行"状态下,在这 ...

  5. JAVA多线程--线程阻塞与唤醒

    方式1:早期JAVA采用suspend().resume()对线程进行阻塞与唤醒,但这种方式产生死锁的风险很大,因为线程被挂起以后不会释放锁,可能与其他线程.主线程产生死锁,如: public cla ...

  6. java notifyall 唤醒顺序_Java线程中的notifyAll唤醒操作(推荐)

    注意: java中的notifyAll和notify都是唤醒线程的操作,notify只会唤醒等待池中的某一个线程,但是不确定是哪一个线程,notifyAll是针对指定对象里面的所有线程执行唤醒操作,指 ...

  7. java基础提升(二):多线程、线程安全、线程状态、等待唤醒机制、线程池

    目录 一. 多线程 1.1并发与并行 1.2 线程与进程 1.3 创建线程类 1.3.1 方式一:继承Thread类 1.3.2 方式二:实现Runnable接口 1.3.3 Thread和Runna ...

  8. 【多线程】java 并发编程中的Condition对象-指定唤醒某个线程

    1.概述 转载:java高并发系列 - 第13天:JUC中的Condition对象 synchronized中实现线程等待和唤醒 Condition简介及常用方法介绍及相关示例 使用Condition ...

  9. java的string访问某个元素_CSS伪类与伪元素总是傻傻分不清,这份总结够面试用了

    熟悉前端的人都会听过 css 的伪类与伪元素,然而大多数的人都会将这两者混淆.本文从解析伪类与伪元素的含义出发,区分这两者的区别,并且列出大部分伪类与伪元素的具体用法,即使你有用过伪类与伪元素,但里面 ...

最新文章

  1. 一个简单的tcpserver
  2. 双轴机械臂串口控制命令开发与测试:STM32F103控制板,简易调试命令集合
  3. 解决url请求参数带中文时后台获取出现乱码问题
  4. 通俗说一下python和人工智能有什么关系
  5. Python中的基本函数及其常用用法简析
  6. 如何使用shell脚本快速排序和去重文件数据
  7. 小程序秒杀活动服务器,微信小程序官方上线张大仙周年活动,人数太多把服务器弄崩溃了...
  8. jpa findone怎么用_Jpa VS MyBatis,你用哪个?
  9. 原生ajax请求的五个步骤
  10. 一行一个链接代码_AI最优论文+代码查找神器:966个ML任务、8500+论文任你选
  11. 安全学习笔记(一)-文件下载以及NC
  12. Python学习3-层次聚类
  13. 交换机分布缓存_缓存比普通交换机也大许多
  14. python爬取微信好友头像_使用python itchat包爬取微信好友头像形成矩形头像集的方法...
  15. zabbix 自带模板监控mysql_zabbix使用自带模板监控mysql
  16. 硬刚ChatGPT!文心一言能否为百度止颓?
  17. 用函数发生器输出高阻态程序
  18. DNSPod十问Fanmart向勇:征战东南亚,跨境电商的新大陆?
  19. 机器视觉光源案例锦集(一)
  20. 运营级低延时网络直播平台建设解决方案

热门文章

  1. python精度_通过Python可以达到的最高时间精度范围是多少?
  2. 旺旺上显示已上传服务器,在服务器上排除问题的头五分钟 | 旺旺知识库
  3. tomcat应用服务器有哪些,2014年最流行的应用服务器排行榜 Tomcat第一
  4. 本地html如何导出pdf,html表格以pdf格式导出到本地
  5. java date 之后_java中时间类(util Date)的后延与前推处理
  6. js 调用c语言函数看,web前端:JS高级---函数中的this的指向,函数的不同调用方式...
  7. centos mysql phpmyadmin_CentOS下phpMyAdmin安装
  8. 面向对象:三大特性与五大原则
  9. 将某一位置1,将某一位置0,判断某一位是否为1
  10. 机器视觉LCD行业质量检测解决方案