`
goodluck_wgw
  • 浏览: 96186 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java中的synchronized、Object.wait()、Object.notify()/notifyAll()原理

    博客分类:
  • java
阅读更多

看到一遍博客介绍Java中的synchronized、Object.wait()、Object.notify()/notifyAll()原理,感觉不错,就贴了过来

 

synchronized与互斥锁mutex

synchronized用来锁定某个对象,体现的是标准的互斥锁mutex的机制,synchronized代码块的开始即是lock该mutex,代码块的结束即是unlock。

Object.wait()与条件变量

Object.wait()在使用时通常要判断是否满足某个条件,不满足某个外部条件cond时调用wait(),来让线程阻塞同时释放被synchronized锁定的mutex;从这个过程看来Object.wait()实际上是起到条件变量的作用,wait()内部实际上先将synchronized锁定的锁释放,之后将当前线程阻塞在某个内置的条件condition上(注意:此condition为内置的,与外部判断的条件cond并非同一个,外部的cond需要程序员根据程序逻辑来判断改变,而这个condition只能被Object.notify()/notifyAll()改变),直到内置条件condition被Object.notify()/notifyAll()修改时才会重新锁定该mutex,继续执行wait()后的代码。

Object.notify()/notifyAll()与条件变量

Object.notify()/notifyAll()实际上只起到一个sinal内置条件变量的作用,调用Object.notify()/notifyAll()之后,这个时候其他处于wait()中的线程所等待的内置条件变量已经满足,但是由于wait()中仍然需要lock mutex,而在Object.notify()/notifyAll()中没有把mutex释放掉,故阻塞在wait()处的线程继续等待,但等待的条件不再是内置条件变量而是锁mutex;直到synchronized代码块结束时,由于会自动释放被synchronized锁定的mutex,故此时所有在wait()中等待mutex的线程开始竞争mutex,得到该mutex的会继续执行,否则继续等待mutex。

相关代码

1
2
3
4
5
6
7
synchronized (obj) {// 此处相当于mutex=obj,lock(mutex)
    while (!cond) {// 判断外部条件cond,不满足时让线程wait();
        obj.wait();
    }
    // .....执行满足条件cond时的逻辑过程
    obj.notifyAll();// 更改内置条件condition
}// 此处相当于mutex=obj,unlock(mutex)

obj.wait()内部实现(伪代码):

1
2
3
4
5
wait() {
    unlock(mutex);//解锁mutex
    wait_condition(condition);//等待内置条件变量condition
    lock(mutex);//竞争锁
}

obj.notify()/notifyAll()内部实现(伪代码):

1
2
3
obj.notify()/notifyAll(){
    condition=true;//只起到把内置条件变量置为true的作用
}

注意:该代码中之所以用while循环判断该外部条件cond,是因为,第一次Object.notify()/notifyAll()被调用之后,所有线程所等待的内部条件condition都已经满足。此时所有线程竞争mutex,而mutex只会被其中一个线程获得,其余线程继续等待在mutex上。当获得mutex的那个线程执行结束时,所有线程又会竞争mutex,此时,某个线程因为获得了mutex而继续执行。 但这个过程中该线程并没有判断外部条件cond是否成立。 也许在第一次获得mutex的线程中已经将外部条件cond改变为false,而当前获得mutex的线程没有判断cond是否为true而直接执行了后续的代码,相当于通过漏洞执行了后续的代码,必然导致程序逻辑的错误。故,必须用while判断外部条件。同时,由此得出,wait和notify所等待和改变的内置条件变量condition一定在obj对象中,只有这样所有被锁定在obj上的线程才能共享该condition。故可以做这样的推断:
被synchronized锁定的mutex为mutex =obj.mutex;
被wait和notify共享的内置条件变量condition = obj.condition;

总结

在使用synchronized、Object.wait()、Object.notify()/notifyAll()实现线程同步时,用到了两种机制:线程互斥锁mutex和条件变量condition。

分享到:
评论

相关推荐

    Java 同步方式 wait和notify/notifyall

    在Java中,`wait()`, `notify()`, 和 `notifyAll()` 是Java Object类的三个方法,它们在实现线程间通信和协作时扮演着关键角色。这些方法主要用于解决线程等待和唤醒的问题,是基于Java Monitor(监视器)模型的。 ...

    Object.wait()与Object.notify()的用法详细解析

    Java中的`Object.wait()`、`Object.notify()`以及`Object.notifyAll()`是多线程编程中的核心方法,它们用于实现线程间的协作与通信。这些方法是`Object`类的最终原生(`final native`)方法,这意味着它们的实现位于...

    Java多线程wait和notify

    在Java中,`wait()` 和 `notify()` 方法是实现线程间通信和协作的重要工具,它们属于 `java.lang.Object` 类,这意味着所有类都默认继承了这两个方法。本文将详细探讨如何使用 `wait()` 和 `notify()` 来控制子线程...

    Java多线程中wait、notify、notifyAll使用详解

    Java中多线程编程中,wait、notify、notifyAll三个方法是非常重要的,它们都是Object对象的方法,用于线程之间的通信。下面我们将详细介绍这三个方法的使用和作用。 一、wait()方法 wait()方法是使当前线程自动...

    Java 中Object的wait() notify() notifyAll()方法使用

    Java 中Object的wait() notify() notifyAll()方法使用 在Java并发编程中,Object的wait()、notify()和notifyAll()方法是非常重要的概念,这三个方法都是Object类的方法,可以认为任意一个Object都是一种资源(或者...

    java sleep和wait的解惑.docx

    ### Java中的sleep与wait详解 #### 一、概述 在Java多线程编程中,`Thread.sleep()` 和 `Object.wait()` 是两个非常重要的方法,它们分别位于 `Thread` 类和 `Object` 类中,用于控制线程的行为。本文将深入探讨这...

    Java多线程同步(wait()notify()notifyAll())[文].pdf

    本文将深入探讨Java中的wait()、notify()和notifyAll()方法,以及synchronized关键字和原子操作在多线程环境中的应用。 1. **wait()方法**: - wait()是Object类的一个方法,它的作用是让当前线程暂停执行并释放它...

    详解Java中的sleep()和wait()的区别

    - `wait()` 方法是 `java.lang.Object` 类的一个实例方法,它只能在同步块或同步方法中使用,因为它涉及到对象锁的管理。当一个线程调用对象的 `wait()` 方法时,它会释放当前对象的锁,然后进入该对象的等待池,...

    wait,notify等线程知识.pdf

    在Java中,`wait()` 和 `notify()` 方法用于实现线程间的同步。它们属于 `Object` 类的方法,这意味着所有对象都可以作为同步锁来使用。 ##### 1. wait() `wait()` 方法用于使当前线程进入等待状态,直到其他线程...

    java多线程设计wait.docx

    在Java中,多线程通过共享内存模型实现数据共享,而`synchronized`关键字用来确保同一时刻只有一个线程能够访问特定的资源或代码块。`wait()`和`notify()`方法则是定义在`Object`类中,用于实现线程之间的通信和同步...

    Java的sychronized、wait和notify范例

    在提供的压缩包文件`java_sychronization`中,可能包含了一些示例代码,用于演示如何在Java中使用`synchronized`关键字以及`wait()`和`notify()`方法。通过研究这些样例,你可以更深入地了解这些工具的用法和效果。...

    wait_notify_demo

    `wait()`、`notify()`和`notifyAll()`是Java中的三个关键字,它们属于Object类的方法,主要用于线程间的通信,尤其在实现生产者消费者模式时发挥着重要作用。本文将深入探讨这些方法以及如何在实际场景中应用它们。 ...

    java之wait,notify的用法([ 详解+实例 ])

    在Java多线程编程中,wait和notify是两个非常重要的方法,它们都是Object类的方法,用于线程之间的通信和同步。下面我们将详细解释wait和notify的用法。 wait方法 wait方法是Object类的一个方法,用于让当前线程...

    java-wait和notify的用法.pdf

    在Java编程语言中,`wait()`和`notify()`是Object类中的两个关键方法,它们用于线程间的协作和通信。这两个方法在多线程环境下尤其重要,因为它们允许线程等待特定条件并通知其他线程继续执行。在分析给定的程序之前...

    Java课件\thread.rar

    - **wait(), notify(), notifyAll()**:这些方法用于线程间通信,必须在同步环境中使用,用于让线程在特定条件下等待或唤醒。 - **Condition接口**:`Lock`接口的一部分,提供更灵活的线程等待和唤醒机制。 5. **...

    Monitor.wait例子.rar

    `Monitor`的概念源自操作系统理论,Java中的实现是基于`Monitor`模型的。当一个线程调用对象的`wait()`方法后,它会释放对象的锁,进入等待状态。其他线程可以在此期间获取该锁并执行相应代码。一旦执行完成,或者...

    java基础学习内容

    在Java中,对象提供了一些内置的方法来帮助实现线程间的通信,其中最重要的是`wait()`和`notify()`方法。 - **wait()**:使当前正在执行的线程进入等待状态,并释放持有的锁。其他线程可以获取这个锁并执行相应的...

    Concurrent.Programming.in.Java - Design.Principles.and.Patterns(Second.Edition)

    本节重点讨论了如何利用`Object.wait`、`Object.notify`和`Object.notifyAll`等监控器方法来管理对象的状态,从而实现更高级别的同步。 #### 2.2.2 应用案例 通过实例演示了如何使用这些方法来控制线程的执行顺序,...

    Java wait和notify虚假唤醒原理

    Java中的`wait()`和`notify()`是用于多线程同步的关键方法,它们是Object类的成员,因此所有Java对象都可以调用。这两个方法是Java内存模型(JMM)的一部分,用于控制线程间的协作和通信。 `wait()`方法使得当前...

    java中几个notify、wait使用实例

    `wait()`、`notify()`和`notifyAll()`方法是Java中实现线程同步的关键工具。正确使用它们可以有效避免线程间的竞争条件和死锁问题,同时也能实现线程间的高效通信。在实际开发中,应根据具体的应用场景选择合适的...

Global site tag (gtag.js) - Google Analytics