java等待喚醒機制的使用(wait/notify)

1.B調用A中創建的obj對象的相關屬性

package com.ckx.client;

/**
 * 需求:B的執行需要等待A中obj對象的創建完成才能繼續
 *  因爲B需要A中的obj對象搞事情
 */
public class Wait2Notify {

    static Object obj;
    public static void main(String[] args){
        new Thread(new A()).start();
        new Thread(new B()).start();
    }


   static class A implements Runnable{
        @Override
        public void run() {
            try {
                Thread.sleep(300);
                obj = new Object();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

    static class B implements Runnable{
        @Override
        public void run() {
            System.out.println("obj:"+obj.hashCode());// 調用obj的hashCode()方法
        }
    }
}



結果報錯:原因obj還沒得到初始化,必現等待A初始化完成obj對象後才能調用。

Exception in thread "Thread-1" java.lang.NullPointerException
	at com.ckx.client.Wait2Notify$B.run(Wait2Notify.java:32)
	at java.lang.Thread.run(Thread.java:745)

Process finished with exit code 0

加鎖:notity並不會立即釋放鎖,需要等到執行notify()方法的線程將程序執行完,也就是退出synchronized代碼塊後,當前線程纔會釋放鎖。

package com.ckx.client;

/**
 * 需求:B的執行需要等待A中obj對象的創建完成才能繼續
 *  因爲B需要A中的obj對象搞事情
 */
public class Wait2Notify {

    static Object obj;
   
    static Object lock = new Object();// 帶鎖的對象
    public static void main(String[] args){
        new Thread(new B()).start();
        new Thread(new A()).start();
    }


   static class A implements Runnable{
        @Override
        public void run() {
            synchronized (lock){// 獲取鎖(獲取成功則執行代碼塊,獲取不到只能在此等待)
                try {
                    System.out.println("aaaaaaaaaaa");
                    Thread.sleep(300);

                    obj = new Object();
                    lock.notify();// 喚醒wait
                    System.out.println("ddddddddddd");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }


        }
    }

    static class B implements Runnable{
        @Override
        public void run() {
            synchronized (lock){// 獲取鎖(獲取成功則執行代碼塊,獲取不到只能在此等待)
                while (obj==null){// 如果先得到鎖,則判斷obj是否已經實例化
                    try {
                        System.out.println("bbbbbbbbb");
                        lock.wait();// obj沒初始化則在此等待,,並釋放鎖
                        System.out.println("cccccccccc");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            System.out.println("obj:"+obj.hashCode());
        }
    }
}



如果B線程先執行則輸出:

bbbbbbbbb
aaaaaaaaaaa
ddddddddddd
cccccccccc
obj:1333065970

Process finished with exit code 0

如果A線程先執行則輸出:

aaaaaaaaaaa
ddddddddddd
obj:1333065970

Process finished with exit code 0

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章