线程休眠的两种方式:
1. Thread.sleep()
与锁操作无关,如果该方法恰好在一个锁的保护范围之内,当前线程即使在执行sleep()的时候,仍然继续保持监视锁。
sleep方法实际上仅仅是完成等待或者睡眠的语义
2.Object.wait()
当线程执行到wait()方法上,当前线程会释放监视锁,此时其他线程可以占有该锁
一旦wait()方法执行完成,当前线程又继续持有该锁,直到执行完该锁的作用域.
wait()退出的条件:
1.达到了wait(long timout)指定的时间
2.其他线程调用了notify()或者notifyAll()
如果在同步代码块之外调用wait(),JVM将会抛出IllegalMonitorStateException
线程休眠测试:
public class FileLock implements Runnable {
//打印一次日期休眠1s
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(new Date());
try {
//挂起线程1s
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
throw new RuntimeException("currentThread is interrupted");
}
}
}
public static void main(String[] args) {
FileLock fl = new FileLock();
Thread t = new Thread(fl);
t.start();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
//中断fl线程
t.interrupt();
}
}
如果休眠线程被中断,会立即抛出InterruptedException而不需要等待到线程休眠时间结束
等待线程的终止 ——join
public class TestJoin implements Runnable {
public static void main(String[] args) {
Thread t = new Thread(new TestJoin());
t.start();
//main线程将会线程t执行完毕再执行
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("after join " + new Date());
}
@Override
public void run() {
System.out.println("before join" + new Date());
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}