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