资讯专栏INFORMATION COLUMN

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

seanHai / 381人阅读

摘要:即调用任意对象的方法导致该线程阻塞,该线程不可继续执行,并且该对象上的锁被释放。将所有等待该对象的线程全部唤起。

方法简介 1. wait()
synchronized (lockObjectA) {
try {
    lockObjectA.wait();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

此时,代码块中会释放对对象lockObjectA的锁定,同时使lockObjectA进行等待,直到有线程调用了它的notify()或notifyAll()方法,才继续将lockObjectA锁定,并继续执行下面程序。
即:调用任意对象的 wait() 方法导致该线程阻塞,该线程不可继续执行,并且该对象上的锁被释放。

2. notify()
synchronized (lockObjectA) {
            lockObjectA.notify();
        }

唤醒在等待该对象同步锁的线程(只唤醒一个),在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
即:调用任意对象的notify()方法则导致因调用该对象的 wait()方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。

3. notifyAll()

将所有等待该对象的线程全部唤起。

示例
package Test0315;


/**
 * Created by Cesar on 2016/3/15.
 */
public class TestWait extends Thread {
    private static Object lockObjectA = new Object();
    private int key;

    public TestWait(int key) {
        this.key = key;
    }

    @Override
    public void run() {
        if (key == 0) {
            synchronized (lockObjectA) {
                System.out.println(key + "开始等待");
                try {
                    lockObjectA.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(key + "等待结束");
                System.out.println(key + "成功锁定A");
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(key + "释放A");
        } else if (key == 1) {
            synchronized (lockObjectA) {
                lockObjectA.notify();
            }
            System.out.println(key + "释放了A");
        } else {
            synchronized (lockObjectA){
                System.out.println(3+"锁定了A");
            }
        }
    }


    public static void main(String[] args) {
        TestWait wait = new TestWait(0);
        wait.setName("Test Wait");
        wait.start();
        System.out.println("主线程休眠开始");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("主线程休眠结束,唤醒开始");
        TestWait wait1 = new TestWait(1);
        wait1.start();

        TestWait wait2 = new TestWait(2);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        wait2.start();
        try {
            wait2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("全部结束");
    }
}
结果
主线程休眠开始
0开始等待
主线程休眠结束,唤醒开始
1释放了A
0等待结束
0成功锁定A
0释放A
3锁定了A
全部结束

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65633.html

相关文章

  • Javawait/notify/notifyAll

    摘要:等待一段时间是否有线程唤醒锁,如果没有,超时自动唤醒。随机唤醒等待队列中的等待同一个锁的一个线程,使这个线程退出等待队列,进入可运行状态。条件队列中是处于等待状态的线程,等待特定条件为真。在一般情况下,总应该调用唤醒所有需要被唤醒的线程。 方法 java.lang.Object public final native void wait() throws InterruptedExce...

    terasum 评论0 收藏0
  • JavawaitnotifynotifyAll使用详解

    摘要:用法中规定,在调用者三个方法时,当前线程必须获得对象锁。作用方法作用线程自动释放占有的对象锁,并等待。当生产者生产了一个数据或者消费者消费了一个数据之后,使用方法来通知所有等待当前对象锁的线程,但是一次只会有一个等待的线程能拿到锁。 基础知识 首先我们需要知道,这几个都是Object对象的方法。换言之,Java中所有的对象都有这些方法。 public final native void...

    rozbo 评论0 收藏0
  • java多线程(7)wait()、notify()和notityALL()

    摘要:已经在上面有提到过,和的作用是唤醒正在的线程,是随机唤醒线程中的一个,则是唤醒全部。释放和不释放锁在多线程的操作中,锁的释放与否是必须要清楚的,是会释放锁,而则不会。 wait wait方法是Object中的方法,这个方法的功能特性:1).执行wait方法的前提是当前线程已经获取到对象的锁,也就是wait方法必须在synchronized修饰的代码块或者方法中使用。2).执行wait之...

    LiuRhoRamen 评论0 收藏0
  • java并发编程学习之线程生命周期-wait,notify,notifyall(六)

    摘要:不释放持有的锁,释放锁。在调用方法前,必须持有锁,调用唤醒,也要持有锁。休眠一定时间后,进入就绪状态。这两个都能被方法中断当前状态。用法方获取锁判断条件,不满足继续满足执行其他业务方获取锁改变条件通知为什么是而不是会一直循环,直到条件满足。 sleep和wait sleep是Thread类的方法,wait是Object的方法。 sleep可以到处使用,wait必须是在同步方法或者代码...

    Terry_Tai 评论0 收藏0
  • [Java并发-5]用“等待-通知”机制优化循环等待

    摘要:在这个等待通知机制中,我们需要考虑以下四个要素。何时等待线程要求的条件不满足就等待。是会随机地通知等待队列中的一个线程,而会通知等待队列中的所有线程。 由上一篇文章你应该已经知道,在 破坏占用且等待条件 的时候,如果转出账本和转入账本不满足同时在文件架上这个条件,就用死循环的方式来循环等待,核心代码如下: // 一次性申请转出账户和转入账户,直到成功 while(!actr.apply...

    fxp 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<