public class Testt {
public static ArrayList ls = new ArrayList();
public static void add(Object o) {
ls.add(o);
}
public static int size() {
return ls.size();
}
public static void main(String[] args) throws InterruptedException{
Object obj = new Object();
Thread th1 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (obj) {
System.out.println("Thread1 start");
for (int i = 0; i < 10; i++) {
add(new Object());
System.out.println("add" + i);
if (i == 5) {
System.out.println("th1 i==5 start obj notify");
obj.notify();
System.out.println("th1 i==5 end obj notify");
try {
System.out.println("i==5 start obj.wait");
obj.wait();
System.out.println("Thread1 从wait中唤醒开始执行");
} catch (InterruptedException e) {
// TODO: handle exception
}
System.out.println("th1 end notify ");
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("线程1执行结束");
}
}
}, "THREAD2");
Thread th2 = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("Thread2 start");
synchronized (obj) {
System.out.println("Thread2 start");
System.out.println("thread2 拿到锁");
if(ls.size() != 5) {
try {
System.out.println("thread2 start wait");
obj.wait();
System.out.println("thread2 end wait");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("thread2 rebegin notify");
obj.notify();
try {
Thread.sleep(5000);
} catch (Exception e) {
// TODO: handle exception
}
}
System.out.println("线程2执行结束");
}
}, "THREAD1");
th2.start();
th2.sleep(1000);
th1.start();
}
}
输出结果为:Thread2 start
Thread2 start
thread2 拿到锁
thread2 start wait
Thread1 start
add0
add1
add2
add3
add4
add5
th1 i5 start obj notify
th1 i5 end obj notify
i==5 start obj.wait
thread2 end wait
thread2 rebegin notify
线程2执行结束
Thread1 从wait中唤醒开始执行
th1 end notify
add6
add7
add8
add9
线程1执行结束
可以看到,线程2执行完 notify()方法后,线程2不会马上释放该对象锁,呈 wait状态的线程也不能马上获得该对象锁,要等到线程退出 sychronized代码块后,线程2才会释放锁,而在同步队列中的线程1才可以获取。