这几个用法是很多公司都考的问题,下面再复习一下
package test;
public class MyThread extends Thread {
public static Object lock = new Object() ; //全局的锁,在这用来说明问题
public static int i = 0 ;
public void run(){
synchronized(lock){ //这里同步,如果没有释放锁,其他线程是不会进去执行println语句的
i++ ;
int prev = i ; //用于看是那个线程,局部变量保存在线程栈中
System.out.println("before i = " + i);
try {
lock.wait(); //这里,如果wait不释放锁,其他线程不可能进入打印出“before i =” 信息
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
i++;
System.out.println( prev + " after i = " + i);
}
}
}
public class MyTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
for(int i = 0 ; i < 5 ; i++){
MyThread th = new MyThread();
th.start();
}
try {
Thread.currentThread().sleep(2000); //这里睡眠,让线程先都开始跑
System.out.println("end");
synchronized(MyThread.lock){
MyThread.lock.notifyAll();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行结果
before i = 1
before i = 2
before i = 3
before i = 4
before i = 5
end
5 after i = 6
4 after i = 7
3 after i = 8
2 after i = 9
1 after i = 10
由上面的输出结果可以看出,打印"end",也就是notifyAll()之前,在lock.wait时候,释放了锁,所以其他线程可以进入同步块,输出了 “before i = ” 信息。
上面的wait和notifyAll,如果没有synchronized块,运行时候会抛出IllegalMonitorStateException。