第一章8,9,10页 实现两个线程顺序获取锁。
public class test01 {
//volatile关键字提供内存屏障的方式来防止指令被重排,编译器在生成字节码文件时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。
private static volatile Object resource01 = new Object();
private static volatile Object resource02 = new Object();
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
//创建线程A
Thread threadA = new Thread(new Runnable() {
public void run() { //三条线程以上 ,这里开始 while()
try {
//获取resource01共享资源的监视器锁
synchronized(resource01) {
System.out.println("threadA get resource01 lock");
synchronized(resource02) {
System.out.println("threadA get resource02 lock");
//线程A阻塞,并释放获取到的resource01锁
System.out.println("threadA release resource01 lock");
resource01.wait();
}
}
}catch (InterruptedException e)
{e.printStackTrace();}
} }
) ;
//创建线程
Thread threadB = new Thread(new Runnable() {
public void run() { //三条线程以上 ,这里开始 while()
try {
//休眠本线程1秒
Thread.sleep(1000);
synchronized(resource01) {
System.out.println("threadB get resource01 lock");
synchronized(resource02) {
System.out.println("threadB get resource02 lock");
//线程A阻塞,并释放获取到的resource01锁
System.out.println("threadA release resource01 lock");
resource01.wait();
}
}
}catch (InterruptedException e)
{e.printStackTrace();}
} }
) ;
//两个线程 启动
threadA.start();
threadB.start();
System.out.println("芭比Q了 ");
//等待 两个线程 结束
threadA.join();
threadB.join();
}
}
上述代码中,在main函数中启动了线程threadA和threadB,为了threadA获取到锁,先让threadB休眠1秒。threadA先后获取到共享变量resource01和resource02上的锁,然后调用resource01的wait()方法阻塞自己,释放resource01的锁。
threadB休眠结束后先尝试获取resource01的锁,被阻塞。当threadA释放resource01的锁后,threadB就获取resource01的锁。然后尝试获取resource02的锁,被阻塞。
以上证明了当线程调用共享对象的wait()方法时,当前线程只会释放当前共享对象的锁,当前线程持有的其他共享对象的锁并不会释放。