Java的线程有一个sleep方法,它的目的是让当前正在执行的线程临时的放弃执行,进行休眠一定的时间,过了这个时间后又重新恢复执行。线程在休眠期间它所持有的监视器锁是不会被释放的。这个方法可以普通的调用,也可以在获得锁的情况下调用,只是在休眠期间一直占有锁。
下面是普通调用的实例代码:
Thread t3 = new Thread(new Runnable(){
public void run() {
try {
System.out.println("线程3 -> " + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
Thread.sleep(5000);
System.out.println("线程3 <- " + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
} catch (InterruptedException e) {
e.printStackTrace();
}
}});
Thread t4 = new Thread(new Runnable(){
public void run() {
try {
System.out.println("线程4 -> " + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
Thread.sleep(5000);
System.out.println("线程4 <- " + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
} catch (InterruptedException e) {
e.printStackTrace();
}
}});
t3.start();
Thread.sleep(1000);
t4.start();
下面是执行结果:
线程3 -> 2012-10-30 13:48:16
线程4 -> 2012-10-30 13:48:17
线程3 <- 2012-10-30 13:48:21
线程4 <- 2012-10-30 13:48:22
这两个线程的调用间隔一秒,它们的开始和结束都差一秒,可以看出它们的休眠是互不影响的。这就是普通调用的情况。
下面是在获得监视器锁时调用的实例代码:
final Object monitor = new Object();
Thread t1 = new Thread(new Runnable(){
public void run() {
try {
System.out.println("线程1 等待锁 " + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
synchronized(monitor) {
System.out.println("线程1 获得锁 " + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
Thread.sleep(5000);
System.out.println("线程1 退出锁 " + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}});
Thread t2 = new Thread(new Runnable(){
public void run() {
try {
System.out.println("线程2 等待锁 " + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
synchronized(monitor) {
System.out.println("线程2 获得锁 " + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
Thread.sleep(5000);
System.out.println("线程2 退出锁 " + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}});
t1.start();
Thread.sleep(1000);
t2.start();
下面是执行的结果:
线程1 等待锁 2012-10-30 13:50:23
线程1 获得锁 2012-10-30 13:50:23
线程2 等待锁 2012-10-30 13:50:24
线程1 退出锁 2012-10-30 13:50:28
线程2 获得锁 2012-10-30 13:50:28
线程2 退出锁 2012-10-30 13:50:33
线程间隔一秒调用,线程1马上就获得锁进入休眠,线程2隔一秒后请求锁,但是锁被休眠中的线程1占有着,所以线程2在等待锁,直到线程1休眠结束后把锁释放掉,线程2才获得所,然后休眠,最后退出锁。可以看出在持有监视器的时候休眠,是会一直占有锁的。这就是在获得监视器锁的调用情况。
如文章有错误之处,敬请指出,共同讨论。