java,wait、notify为何需要搭配synchonized使用?

版权声明:本文为博主原创文章,转载请说明出处 https://blog.csdn.net/u010002184/article/details/82964803

先看实例:


class ThreadA {

    static Object o1 = new Object();//可以是任意一个对象,或者自定义的对象

    public static void main(String[] args) {
        ThreadB b = new ThreadB();
        b.start();
        System.out.println("b is start....");
        synchronized (o1)// 主线程获取o1的对象锁
        {
            try {
                System.out
                        .println("Waiting for b to complete...");
                o1.wait();//o1的对象锁释放,主线程进入等待状态
                System.out
                        .println("Completed.Now back to main thread");
            } catch (InterruptedException e) {
            }
        }

  /*      try {
            System.out
                    .println("Waiting for b to complete...");
            o1.wait();//o1的对象锁释放,主线程进入等待状态
            System.out
                    .println("Completed.Now back to main thread");
        } catch (InterruptedException e) {
        }*/

        System.out.println("Total is :" + b.total);
    }
}

class ThreadB extends Thread {
    int total;

    public void run() {
/*        synchronized (o1) {//ThreadB获取o1的对象锁
            System.out.println("ThreadB is running..");
            for (int i = 0; i < 5; i++) {
                total += i;
                System.out.println("total is " + total);
            }
            o1.notify();//ThreadB释放o1的对象锁,通知其他等待o1对象锁的线程继续运行
        }*/

        System.out.println("ThreadB is running..");
        for (int i = 0; i < 5; i++) {
            total += i;
            System.out.println("total is " + total);
        }
        o1.notify();//ThreadB释放o1的对象锁,通知其他等待o1对象锁的线程继续运行
    }
}

输出:

b is start....
Waiting for b to complete...
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at testpackage.ThreadB.run(ThreadA.java:163)

wait是释放锁,前提是当前线程拥有锁,所以需要在同步方法或同步快中;

notify是释放锁,前提是当前线程拥有锁,所以需要在同步方法或同步快中;

等待方遵循的原则: 
- 获取对象的锁 
- 不满足条件 就调用wait()方法 
- 条件满足继续执行 
通知方原则: 
- 获取对象的锁 
- 改变条件, 然后notify

wait源码:

     * @param      timeout   the maximum time to wait in milliseconds.
     * @throws  IllegalArgumentException      if the value of timeout is
     *               negative.
     * @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 <i>interrupted
     *             status</i> of the current thread is cleared when
     *             this exception is thrown.
     * @see        java.lang.Object#notify()
     * @see        java.lang.Object#notifyAll()
     */
    public final native void wait(long timeout) throws InterruptedException;

注意这句:

* @throws  IllegalMonitorStateException  if the current thread is not
*               the owner of the object's monitor.

notify源码:

     * @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()
     */
    public final native void notify();

注意这句:

     * @throws  IllegalMonitorStateException  if the current thread is not
     *               the owner of this object's monitor.

更多可见:

https://blog.csdn.net/u010002184/article/details/82965536

猜你喜欢

转载自blog.csdn.net/u010002184/article/details/82964803