转自:http://ifeve.com/think-in-java-monitor/

如果你在大学学习过操作系统,你可能还记得监听器在操作系统中是很重要的概念。同样监听器在java同步机制中也有使用,本文通过类比的方法来解释“监听器”的基本思想。

什么是监听器?

监听器可以看成是包含了一间特殊房间的建筑,这间特殊的房间在同一个时间只能被一个客人(线程)拥有,通常这间房间包含了一些数据和代码。

如果一个客人想拥有这间特殊的房间,他不得不首先在走廊(进入集)中等待着,然后调度器根据一些调度算法(eg:FIFO 先进先出)选择一个。如果这个客人因为某些原因暂停悬挂着,则会被放到等待房间`,同时也被安排稍后重新进入这个特殊的房间,就像上面图片所展示的那样,在这个建筑里有个3个房间。

简而言之:一个监听器就是一个监听线程进入这间特殊房间的设施。它确保了只能有一个线程可以访问这些受到保护的数据和代码。

在java中监听器是如何实现的?

在java虚拟机中,每个对象和类在逻辑上都和一个监听器相关联。为了实现监听器的共同执行能力,锁(有时候又叫互斥量)关联着每个对象和类,在操作系统书上被称之为“信号量”,互斥量其实就是一个二态的信号量。

如果一个线程拿到了相关数据的锁,那么其他线程不能再拥有这把锁直到拥有这把锁的线程释放了这把锁。当在多线程编程中,如果我们需要一直写一个信号量这种方式可能会不太方便,幸运的是我们没必要这么做,因为JVM(java虚拟机)已经自动帮我们做了。

声明一个监听器区域,这意味着数据不能被超过一个线程访问(译者注:同时访问的前提)。Java提供了同步的语句和同步的方法,一旦代码嵌入到同步关键字内,这就是一个监听器区域。而锁是由jvm在底层自动实现的。

在java同步代码中,哪部分才是监听器?

我们知道每个对象/类都关联着一个监听器,我觉得这么说好点,每个对象都拥有一个监听器,因为每个对象都有它关键的区域和监听线程队列的能力。

为了使不同线程能相互合作,java提供了wait()和notify()方法来暂停一个线程和唤醒分别等待访问这个对象的其他线程中的一个,另外还有3个其他版本:

wait(long timeout, int nanos)
wait(long timeout) notified by other threads or notified by timeout.
notify(all)

这些方法只能在一个同步语句或者同步方法内调用,原因是因为如果一个方法不要求互斥,那么就没有必要在线程间监听或者是合作,每个线程都可以自由访问这个方法。

这里是一些同步代码的例子。

参考资料

1. Java Doc for Object

2. Thread synchronization
3. Locks and Synchronization
4. notify() vs notifyAll()

【线程系列四】[转]监听器-java同步的基本思想的更多相关文章

  1. 监视锁——Java同步的基本思想

    翻译人员: 铁锚翻译时间: 2013年11月13日原文链接: Monitors – The Basic Idea of Java synchronization如果你上过操作系统课程,你就知道监视锁( ...

  2. 锁——Java同步的基本思想

    翻译人员: 铁锚 翻译时间: 2013年11月13日 原文链接:  Monitors – The Basic Idea of Java synchronization 如果你上过操作系统课程,你就知道 ...

  3. 死磕 java同步系列之zookeeper分布式锁

    问题 (1)zookeeper如何实现分布式锁? (2)zookeeper分布式锁有哪些优点? (3)zookeeper分布式锁有哪些缺点? 简介 zooKeeper是一个分布式的,开放源码的分布式应 ...

  4. java多线程系列(四)---Lock的使用

    Lock的使用 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理 ...

  5. java多线程系列(四)---ReentrantLock的使用

    Lock的使用 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我的理 ...

  6. 死磕 java同步系列之volatile解析

    问题 (1)volatile是如何保证可见性的? (2)volatile是如何禁止重排序的? (3)volatile的实现原理? (4)volatile的缺陷? 简介 volatile可以说是Java ...

  7. 死磕 java同步系列之redis分布式锁进化史

    问题 (1)redis如何实现分布式锁? (2)redis分布式锁有哪些优点? (3)redis分布式锁有哪些缺点? (4)redis实现分布式锁有没有现成的轮子可以使用? 简介 Redis(全称:R ...

  8. 死磕 java线程系列之线程池深入解析——普通任务执行流程

    (手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 注:线程池源码部分如无特殊说明均指ThreadPoolExecutor类. 简介 前面我们一起学习了Java中 ...

  9. 死磕 java线程系列之线程池深入解析——未来任务执行流程

    (手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 注:线程池源码部分如无特殊说明均指ThreadPoolExecutor类. 简介 前面我们一起学习了线程池中普 ...

随机推荐

  1. 演练Ext JS 4.2自定义主题

    本文将根据API文档中关于主题的介绍做的一次演练,以便熟悉自定义主题的过程. 练习环境: Sencha Cmd v4.0.1.45 Ruby 1.9.3-p392 firefox 26 首先,使用以下 ...

  2. 优秀设计师应当知道的20大UI设计原则

    世界级图形设计大师Paul Rand(保罗.兰德)曾经说过:"设计绝不是简单的排列组合与简单地再编辑,它应当充满着价值和意义,去说明道理,去删繁就简,去阐明演绎,去修饰美化,去赞美褒扬,使其 ...

  3. 苹果新的编程语言 Swift 语言进阶(七)--枚举、结构、类

    Swift语言中,具有类特征的类型包括三种,即枚举类型.结构类型(包括基本类型,基本类型实际都是结构类型的特例).类.其中枚举类型.结构类型是属于值类型,类属于引用类型.三种类型都可以添加属性.方法. ...

  4. DBUS基础知识

    转:http://www.cnblogs.com/wzh206/archive/2010/05/13/1734901.html DBUS基础知识 1.  进程间使用D-Bus通信 D-Bus是一种高级 ...

  5. 【Qt编程】基于Qt的词典开发系列<五>--无边框窗口的拖动

    在上一篇文章中,我们讲述了如何进行无边框窗口的缩放与拖动,而在一些情况下,我们的窗口只需要进行拖动也不需要改变其大小,比如:QQ的登录窗口.本来在上一篇文章中已经讲述了如何进行窗口的拖动,但是却与窗口 ...

  6. ubuntu下无法编译ruby-2.1.5提示something wrong with CFLAGS -arch x86_64

    在Mac OS X10.10下以下语句运行没有问题: ./configure -prefix=/Users/apple/src/ruby_src/ruby2.1.5_installed --with- ...

  7. JAVA物联网九大核心热点技术

    1. Unix/Linux平台技术: Unix系统原理.Unix常用命令.Shell编程.  2. Java EE核心技术: Java语言核心.Java高级API.JVM及性能优化.Java Secu ...

  8. JavaScript中对象数组 根据某个属性值 然后push到新的数组

    原文链接 https://segmentfault.com/q/1010000010075035 将下列对象数组中,工资大于1w的员工,增加到对象数组 WanSalary中 var BaiduUser ...

  9. Mybatis 系列5

    上篇系列4中 为大家介绍了mybatis中别名的使用,以及其源码.本篇将为大家介绍TypeHandler, 并简单分析其源码. Mybatis中的TypeHandler是什么? 无论是 MyBatis ...

  10. Ubuntu设置代理的方法

    用过Linux的都知道,众多的PROXY配置,让人应接不暇,本文列出常见的一些PROXY的配置 1.apt-get proxy 的配置sudo gedit /etc/apt/apt.conf NOTE ...