JAVA基础多线程(二)线程等待和唤醒wait()、notify()注释源码分析

本文深入分析JAVA中Object类的wait(), notify()和notifyAll()方法,包括它们的作用、使用场景及区别。通过实例解释wait()为何要放在while循环中,以及wait/notify可能导致的性能问题,如过早唤醒和信号丢失。" 101273101,7587612,TI TMS320C6678 + Xilinx Kintex-7 FPGA开发板应用详解,"['嵌入式系统', 'DSP开发', 'FPGA设计', '高速接口', '多核处理器']
摘要由CSDN通过智能技术生成

本文参考了此博客部分内容:http://www.cnblogs.com/skywang12345/p/3479224.html

概述

在Object类中,定义了wait(), notify()和notifyAll()等接口。wait()的作用是让当前线程进入等待状态,同时,wait()也会让当前线程释放它所持有的锁。而notify()和notifyAll()的作用,则是唤醒当前对象上的等待线程;notify()是唤醒单个线程,而notifyAll()是唤醒所有的线程。

wait()

参考注释

节选了部分核心注释,理解它很有帮助

    /**
     * 调用wait的当前线程必须拥有该对象的锁
     * The current thread must own this object's monitor.
     * 
     * 这个方法会使当前线程将自己放入对象的等待集合,然后放弃它持有的锁,线程将暂时不会被调度并处于休眠状态,
     * 直到以下四种情况之一的发生:
     * This method causes the current thread (call it <var>T</var>) to
     * place itself in the wait set for this object and then to relinquish
     * any and all synchronization claims on this object. Thread <var>T</var>
     * becomes disabled for thread scheduling purposes and lies dormant
     * until one of four things happens:
     * 
     * ①其他线程调用同一个对象的notify方法,而此线程正好是被随机选中要唤醒的线程
     * Some other thread invokes the {@code notify} method for this
     * object and thread <var>T</var> happens to be arbitrarily chosen as
     * the thread to be awakened.
     * 
     * ②其他线程调用了同一个对象的notifyAll方法
     * Some other thread invokes the {@code notifyAll} method for this
     * object.
     * 
     * ③其他线程中断了该线程
     * Some other thread {@linkplain Thread#interrupt() interrupts}
     * thread <var>T</var>.
     * 
     * ④wait(long waitTime)参数中的等待时间过去了,如果等待时间为0则会一直等待唤醒
     * The specified amount of real time has elapsed, more or less.  If
     * {@code timeout} is zero, however, then real time is not taken into
     * consideration and the thread simply waits until notified.
     * 
     *  线程在被唤醒后,将会从该对象的等待集中删除,并重新启动线程调度,
     * 在与其他线程竞争到锁后,wait方法才返回。对象和线程的状态将会与调用wait时完全相同
     * The thread <var>T</var> is then removed from the wait set for this
     * object and re-enabled for thread scheduling. It then competes in the
     * usual manner with other threads for the right to synchronize on the
     * object; once it has gained control of the object, all its
     * synchronization claims on the object are restored to the status quo
     * ante - that is, to the situation as of the time that the {@code wait}
     * method was invoked. Thread <var>T</var> then returns from the
     * invocation of the {@code wait} method. Thus, on return from the
     * {@code wait} method, the synchronization state of the object and of
     * thread {@code T} is exactly as it was when the {@code wait} method
     * was invoked.
     * 
     * 此方法只能由该对象监视器的所有者线程调用,查看notify方法,了解如何成为监视器所有者。
     * This method should only be called by a thread that is the owner
     * of this object's monitor. See the {@code notify} method for a
     * description of the ways in which a thread can become the owner of
     * a monitor.

notify()、notifyAll()

参考注释

notify()

/**
     * 如果有任何线程在等待此对象监视器(锁),则随机选择其中一个线程唤醒。
     * 线程调用wait方法来等待对象的监视器(锁)
     * Wakes up a single thread that is waiting on this object's
     * monitor. If any threads are waiting on this object, one of them
     * is chosen to be awakened. The choice is arbitrary and occurs at
     * the discretion of the implementation. A thread waits on an object's
     * monitor by calling one of the {@code wait} methods.
     *
     * 被唤醒的对象并不会立马开始执行,必须等到当前线程释放该对象上的锁,然后被
     * 唤醒的线程将会公平的与其他线程进行竞争该锁。
     * The awakened thread will not be able to proceed until the current
     * thread relinquishes the lock on this object. The awakened thread will
     * compete in the usual manner with any other threads that might be
     * actively competing to synchronize on this object; for example, the
     * awakened thread enjoys no reliable privilege or disadvantage in being
     * the next thread to lock this object.
     * 
     * notify方法必须是持有该对象的监视器的线程才能够调用,以下有三种方法可以成为监视器的拥有者
     *  <p>
     * This method should only be called by a thread that is the owner
     * of this object's monitor. A thread becomes the owner of the
     * object's monitor in one of three ways:
     * <ul>
     * 执行该对象的同步方法
     * <li>By executing a synchronized instance method of that object.
     * 执行在该对象上同步的同步代码块
     * <li>By executing the body of a {@code synchronized} statement
     *     that synchronizes on the object.
     * 执行类对象的静态方法
     * <li>For objects of type {@code Class,} by executing a
     *     synchronized static method of that class.
     * </ul>
     * <p>
     * 在同一时间只能有一个线程拥有对象的监视器(锁)
     * Only one thread at a time can own an object's monitor.
     * 

notifyAll()与notify()大致相同,这里只列出不同的

/**
	* 唤醒此对象监视器上的所有线程,对象通过wait方法来等待对象的监视器
     * Wakes up all threads that are waiting on this object's monitor. A
     * thread waits on an object's monitor by calling one of the
     * {@code wait} methods.
     */ 

实例

wait()和notify()

这里使用一个经典的例子加深对wait的理解

// WaitTest.java的源码
class ThreadA extends Thread{
   

    public ThreadA(String name) {
   
        super(name);
    }

    public void run() {
   
        synchronized (this) {
   
            System.out.println(Thread.currentThread().getName()+" call notify()");
            // 唤醒当前的wait线程
            notify();
        }
    }
}

public class WaitTest {
   

    public static void main(String[] args) {
   

        ThreadA t1 = new ThreadA("t1");

        synchronized(t1) {
   
            try {
   
                // 启动“线程t1”
                System.out.println(Thread.currentThread().getName()+" start t1");
                t1.start();

                // 主线程等待t1通过notify()唤醒。
                System.out.println(Thread
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值