线程同步之wait/notify

一直对线程同步的wait/notify不太理解, 今天有空demo实践了下

public class Test {
    private static final Object lock = new Object();

    public static void main(String[] args) {
        testWaitAndNotify();
    }

    private static void testWaitAndNotify() {
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    while (true) {
                        System.out.println("thread1 的run 方法-准备睡两秒->" + System.currentTimeMillis());
                        try {
                            Thread.sleep(2000);
                            System.out.println("thread1 -醒了释放锁了-自己wait->" + System.currentTimeMillis());(1)
                            lock.notify();
                            System.out.println("thread1 -我在睡3秒后才会释放锁->" + System.currentTimeMillis());
                            Thread.sleep(3000);
                            lock.wait();(1)
                            System.out.println("thread1 被叫醒了-->" + System.currentTimeMillis());
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        thread1.start();
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    while (true) {
                        System.out.println("thread2 的run 方法-->准备睡两秒->" + System.currentTimeMillis());
                        try {
                            Thread.sleep(2000);
//                            lock.wait();
                            System.out.println("thread2醒了释放锁了-自己wait-->" + System.currentTimeMillis());
                            lock.notify();
                            System.out.println("thread2 -我在睡3秒后才会释放锁->" + System.currentTimeMillis());
                            Thread.sleep(3000);
                            lock.wait();(2)
                            System.out.println("thread2 被叫醒了-->" + System.currentTimeMillis());
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        thread2.start();

    }
}
image.png

可以看到,thread1先拿到锁并得到执行,然后在(1)处执行wait让出锁,然后,thread2拿到锁,并得到执行,并在(2)处执行wait释放锁,然后需要注意的是,本线程是在notify所在代码块执行完毕后,才有机会竞争该把锁

 /**
     * Causes the current thread to wait until another thread invokes the
     * {@link java.lang.Object#notify()} method or the
     * {@link java.lang.Object#notifyAll()} method for this object.
     * In other words, this method behaves exactly as if it simply
     * performs the call {@code wait(0)}.
     * 

* The current thread must own this object's monitor. The thread * releases ownership of this monitor and waits until another thread * notifies threads waiting on this object's monitor to wake up * either through a call to the {@code notify} method or the * {@code notifyAll} method. The thread then waits until it can * re-obtain ownership of the monitor and resumes execution. *

* As in the one argument version, interrupts and spurious wakeups are * possible, and this method should always be used in a loop: *

     *     synchronized (obj) {
     *         while (<condition does not hold>)
     *             obj.wait();
     *         ... // Perform action appropriate to condition
     *     }
     * 
* 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. * * @throws IllegalMonitorStateException if the current thread is not * the owner of the object's monitor. * @throws InterruptedException if any thread interrupted the * current thread before or while the current thread * was waiting for a notification. The interrupted * status of the current thread is cleared when * this exception is thrown. * @see java.lang.Object#notify() * @see java.lang.Object#notifyAll() */ @FastNative public final native void wait() throws InterruptedException; /** * 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. *

* 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: *

    *
  • By executing a synchronized instance method of that object. *
  • By executing the body of a {@code synchronized} statement * that synchronizes on the object. *
  • For objects of type {@code Class,} by executing a * synchronized static method of that class. *
*

* Only one thread at a time can own an object's monitor. * * @throws IllegalMonitorStateException if the current thread is not * the owner of this object's monitor. * @see java.lang.Object#notifyAll() * @see java.lang.Object#wait() */ @FastNative public final native void notify(); /** * 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. *

* The awakened threads will not be able to proceed until the current * thread relinquishes the lock on this object. The awakened threads * will compete in the usual manner with any other threads that might * be actively competing to synchronize on this object; for example, * the awakened threads enjoy no reliable privilege or disadvantage in * being the next thread to lock this object. *

* 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. * * @throws IllegalMonitorStateException if the current thread is not * the owner of this object's monitor. * @see java.lang.Object#notify() * @see java.lang.Object#wait() */ @FastNative public final native void notifyAll();

(1).wait(),notify(),notifyAll()都是本地方法,并且为final方法,无法被重写
(2).wait(),notify(),notifyAll(),是object的方法,不是Thread的方法
(3).调用某个对象的wait()的方法能让当前线程阻塞,并且,当前线程必须拥有此对象的monitor
(4).调用某个对象的notify()方法能够唤醒一个正在等待这个对象monitor的线程,度过由多个线程在等待这个monitor,则只能唤醒其中一个(按等待顺序)
(5).调用notifyAll()能狗焕醒所有正在等待这个对象的monitor的线程

你可能感兴趣的:(线程同步之wait/notify)