`

wait,notify和notifyall应该注意的问题

阅读更多
在使用wait,notify和notifyall可能会抛出java.lang.IllegalMonitorStateException
首先我们先看看java.lang.IllegalMonitorStateException的说明:
public class IllegalMonitorStateExceptionextends RuntimeException

抛出的异常表明某一线程已经试图等待对象的监视器,或者试图通知其他正在等待对象的监视器而本身没有指定监视器的线程。 

从以下版本开始: 
JDK1.0 


然后再贴2段代码,首先是一个会抛出该异常的代码
package com.wikimore.threadtest;


/**
 * Hello world!
 * 
 */
public class App {

    private static Object lock = new Object();

    public static void main(String[] args) {
        Runnable r1 = new Runnable() {

            public void run() {
                System.out.println("t1 running");
                    try {
                        System.out.println("t1 waiting");
                        lock.wait();
                    }
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("t1 running again");
                    lock.notifyAll();
            }
        };
        Thread t1 = new Thread(r1, "thread-1");
        Runnable r2 = new Runnable() {

            public void run() {
                System.out.println("t2 running");
                    try {
                        System.out.println("t2 waiting");
                        lock.wait();
                    }
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("t2 running again");
                    lock.notifyAll();
            }
        };
        Thread t2 = new Thread(r2, "thread-2");

        Runnable r3 = new Runnable() {

            public void run() {
                System.out.println("t3 running");
                    try {
                        System.out.println("t3 waiting");
                        lock.wait(1000);
                    }
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("t3 running again");
                    lock.notifyAll();
            }
        };
        Thread t3 = new Thread(r3, "thread-3");
        t1.start();
        t2.start();
        t3.start();
    }
}

这段代码的线程在调用wait和notifyall方法时,均没有获得lock的同步锁,等于是没有指定监视器。

再来一段不会抛出异常的代码:
package com.wikimore.threadtest;

/**
 * Hello world!
 * 
 */
public class App {

    private static Object lock = new Object();

    public static void main(String[] args) {
        Runnable r1 = new Runnable() {

            public void run() {
                System.out.println("t1 running");
                synchronized (lock) {
                    try {
                        System.out.println("t1 waiting");
                        lock.wait();
                    }
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("t1 running again");
                    lock.notifyAll();
                }
            }
        };
        Thread t1 = new Thread(r1, "thread-1");
        Runnable r2 = new Runnable() {

            public void run() {
                System.out.println("t2 running");
                synchronized (lock) {
                    try {
                        System.out.println("t2 waiting");
                        lock.wait();
                    }
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("t2 running again");
                    lock.notifyAll();
                }
            }
        };
        Thread t2 = new Thread(r2, "thread-2");

        Runnable r3 = new Runnable() {

            public void run() {
                System.out.println("t3 running");
                synchronized (lock) {
                    try {
                        System.out.println("t3 waiting");
                        lock.wait(10000);
                    }
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("t3 running again");
                    lock.notifyAll();
                }
            }
        };
        Thread t3 = new Thread(r3, "thread-3");
        t1.start();
        t2.start();
        t3.start();
    }
}


这段代码在运行wait方法前会获得lock的同步,故不会出现上述异常。

wait方法执行时会释放锁,所以如果不在同步块中执行的话,很可能就会出现异常。

与wait相似的sleep方法在执行时就不会释放锁,这个需要注意防止阻塞!
分享到:
评论

相关推荐

    Java 同步方式 wait和notify/notifyall

    需要注意的是,`wait()`, `notify()`, 和 `notifyAll()` 必须在同步上下文中(synchronized代码块或方法)调用,否则会抛出`IllegalMonitorStateException`异常。此外,调用这些方法的线程必须是拥有对象锁的线程,...

    如何在Java中正确使用 wait, notify 和 notifyAll

    wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视。本文对这些关键字的使用进行了描述。  在 Java 中可以用 wait、notify 和 notifyAll 来实现...

    源码—Java多线程5—死锁和wait notify notifyAll

    源码—Java多线程5—死锁和wait notify notifyAll

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

    四、wait、notify、notifyAll方法的使用注意事项 1. wait()、notify/notifyAll() 方法是Object的本地final方法,无法被重写。 2. wait()方法使当前线程阻塞,前提是 必须先获得锁,一般配合synchronized 关键字使用...

    Java notify和notifyAll的区别和相同

    Java中的`notify`和`notifyAll`是多线程编程中的关键方法,它们用于线程间的通信,特别是在处理同步机制时。这两个方法都是在`Object`类中定义的,因此可以应用于任何Java对象。 首先,我们需要理解Java的同步机制...

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

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

    【并发编程】 — 线程间的通信wait、notify、notifyAll

    文章目录1 wait、notify、notifyAll简单介绍1.1 使用方法 + 为什么不是Thread类的方法1.2 什么时候加锁、什么时候释放锁?1.3 notify、notifyAll的区别2 两个比较经典的使用案例2.1 案例1 — ABCABC。。。三个线程...

    wait()、notify()和notifyAll()方法1---马克-to-win java视频

    wait()、notify()和notifyAll()方法1---马克-to-win java视频

    wait()、notify()和notifyAll()方法2---马克-to-win java视频

    wait()、notify()和notifyAll()方法2---马克-to-win java视频

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

    在并发编程中,线程安全是非常重要的,wait()、notify()和notifyAll()方法就是为了解决线程安全问题的。 一、前言 在并发编程中,除了Thread外,对Object对象的wait()和notify()方法也应该深入了解其用法,虽然知识...

    Java多线程wait和notify

    需要注意的是,`wait()`、`notify()` 和 `notifyAll()` 必须在同步块或同步方法中调用,以避免出现 `IllegalMonitorStateException`。此外,`InterruptedException` 在 `wait()` 中应该被妥善处理,通常是重新抛出或...

    wait和notifyAll方法的使用示例

    ### 使用wait和notifyAll方法详解 #### 一、引言 在Java多线程编程中,`wait()` 和 `notifyAll()` 方法是非常重要的同步机制,主要用于实现线程间的通信与同步控制。通过合理运用这些方法,可以有效地解决生产者...

    wait_notify_demo

    总结来说,Java的`wait()`、`notify()`和`notifyAll()`方法是实现多线程间协作的关键工具,特别是对于解决生产者消费者问题。理解它们的工作原理和正确使用方式对于编写高效的并发代码至关重要。在上述示例中,我们...

    Java多线程基础 线程的等待与唤醒(wait、notify、notifyAll)

    Java多线程基础中的线程等待与唤醒是一种常见的线程协作机制,通过wait()、notify()和notifyAll()方法来实现线程之间的同步和通信。在本节中,我们将详细介绍wait()、notify()和notifyAll()方法的使用和实现原理。 ...

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

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

    基于Java多线程notify与notifyall的区别分析

    本文将深入探讨`notify()`和`notifyAll()`的区别及其在实际使用中的注意事项。 `wait()`方法使当前线程进入等待状态,并释放它所持有的对象锁。只有在持有该对象锁的情况下,线程才能调用`wait()`。当其他线程调用...

    Java的wait(), notify()和notifyAll()使用心得

    Java中的`wait()`, `notify()`, 和 `notifyAll()` 是多线程编程中的关键工具,它们用于在并发环境中协调线程间的交互。这些方法都定义在`java.lang.Object`类中,因为它们与对象的监视器(monitor)概念密切相关。...

    深入理解Wait、Notify和Wait与sleep区别

    在实际开发中,`wait()`, `notify()`和`notifyAll()`常用于实现生产者-消费者模型、哲学家就餐问题等经典并发问题。它们提供了一种精细控制线程间交互的方式,但使用时需谨慎,避免死锁和活锁的发生。 总之,理解和...

    wait,notify等线程知识.pdf

    使用wait/notify机制时,需要注意死锁和活锁问题。死锁发生在两个或更多线程互相等待对方释放资源的情况下。活锁则是线程不断尝试获取资源但一直失败,导致无限期阻塞。合理设计同步策略和避免这些情况是多线程编程...

    Java 同步锁 wait notify 学习心得

    标题和描述概述的知识点主要集中在Java的多线程机制中,特别是`wait`和`notify`方法在同步锁中的应用。这些方法对于控制线程之间的交互至关重要,尤其是在资源有限或需要确保数据一致性的情况下。 ### Java同步锁...

Global site tag (gtag.js) - Google Analytics