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