Java 多线程基础(七)线程休眠 sleep

一、线程休眠 sleep

sleep() 方法定义在Thread.java中,是 static 修饰的静态方法。
sleep() 的作用是让当前线程休眠,即当前线程会从“运行状态”进入到“休眠(阻塞)状态”。sleep()会指定休眠时间,线程休眠的时间会大于/等于该休眠时间;在线程重新被唤醒时,它会由“阻塞状态”变成“就绪状态”,从而等待cpu的调度执行。

二、sleep示例

public class SleepTest {
private static Object obj = new Object();
public static void main(String[] args) {
Thread t1 = new MyThread("t1");
t1.start();
} static class MyThread extends Thread{
public MyThread(String name) {
super(name);
}
public void run() {
synchronized (obj) {
try {
for(int i = 0;i < 5;i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);
if (i % 4 == 0)
Thread.sleep(1000);// i能被4整除时,休眠1秒
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
}
}
// 运行结果
t1--0
t1--1
t1--2
t1--3
t1--4

说明:

在主线程main中启动线程t1。t1启动之后,当t1中的计算i能被4整除时,t1会通过Thread.sleep(100)休眠100毫秒。

三、sleep(long millis) 与 wait(long timeout)

我们知道,wait()的作用是让当前线程由“运行状态”进入“等待(阻塞)状态”的同时,也会释放同步锁。而sleep()的作用是也是让当前线程由“运行状态”进入到“休眠(阻塞)状态”。
但是,wait() 会释放对象的同步锁,而 sleep() 则不会释放锁

通过下面的代码,演示 sleep() 不会释放锁的:

public class SleepTest {
private static Object obj = new Object();
public static void main(String[] args) {
Thread t1 = new MyThread("t1");
Thread t2 = new MyThread("t2");
t1.start();
t2.start();
} static class MyThread extends Thread{
public MyThread(String name) {
super(name);
}
public void run() {
synchronized (obj) {
try {
for(int i = 0;i < 5;i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);
               Thread.sleep(1000);// 休眠1秒
}
}catch(Exception e) {
e.printStackTrace();
} }
}
}
}
// 执行结果
t1--0
t1--1
t1--2
t1--3
t1--4
t2--0
t2--1
t2--2
t2--3
t2--4

说明:

主线程main中启动了两个线程t1和t2。t1和t2在run()会引用同一个对象的同步锁,即synchronized(obj)。在t1运行过程中,虽然它会调用Thread.sleep(1000) 进入休眠状态;但是,t2是不会获取CPU执行权的。因为,t1并没有释放“obj所持有的同步锁”!
注意,若我们注释掉 synchronized (obj) 后再次执行该程序,t1和t2是可以相互切换执行的,原因是:在没有同步锁的情况下,当一个线程进入“休眠(阻塞)状态“时,会放弃CPU的执行权,另一个线程就会获取CPU执行权。

通过下面的代码,演示 wait() 会释放锁的:

public class SleepTest {
private static Object obj = new Object();
public static void main(String[] args) {
Thread t1 = new MyThread("t1");
Thread t2 = new MyThread("t2");
t1.start();
t2.start();
} static class MyThread extends Thread{
public MyThread(String name) {
super(name);
}
public void run() {
synchronized (obj) {
try {
for(int i = 0;i < 5;i++) {
System.out.println(Thread.currentThread().getName() + "--" + i);
obj.wait(1000);// 等待1秒
}
}catch(Exception e) {
e.printStackTrace();
} }
}
}
}
// 执行结果
t1--0
t2--0
t1--1
t2--1
t2--2
t1--2
t2--3
t1--3
t2--4
t1--4

说明:

主线程main中启动了两个线程t1和t2。t1和t2在run()会引用同一个对象的同步锁,即synchronized(obj)。在t1运行过程中,调用 obj.wait(1000) 进入等待状态,释放同步锁;此时,t2会获取CPU执行权的。

最新文章

  1. 【BZOJ-1962】模型王子 DP 猜数问题
  2. intellij idea 14 ULTIMATE 注册码
  3. linux命令sed学习笔记
  4. [Java] JavaMail 发送 html 格式、带附件的邮件
  5. 重温Java的类加载机制
  6. poj 3287 The Trip, 2007_贪心
  7. RequireJS简单实用说明
  8. 在tomcat中加入SSL腾讯云证书的步骤
  9. django 视图模式
  10. 升级openssl 操作记录
  11. Ubuntu、deepin 支持 yum
  12. CSS【04】:CSS组合选择器
  13. 记前些日子archlinux更新后无法调节声音的解决方法
  14. JMeter性能(压力)测试--使用解锁
  15. PHPCMS v9上传图片提示&quot;undefined&quot;的解决办法
  16. 25.Reverse Nodes in k-Group (List)
  17. Oracle下如何设置 log_archive_dest
  18. Petrozavodsk Winter Training Camp 2018
  19. poi导出excle测试类
  20. 如何修改或美化linux终端

热门文章

  1. C#中操作JSON
  2. Java获取主板序列号、MAC地址、CPU序列号工具类
  3. 解决google play上架App设置隐私政策声明问题
  4. 浅谈SIEM
  5. Jmeter(五) - 从入门到精通 - 创建网络计划实战和创建高级Web测试计划(详解教程)
  6. (String),toString(),String.valueOf()
  7. Spring-boot01
  8. Java实现 LeetCode 815 公交路线(创建关系+BFS)
  9. Java实现 LeetCode 641 设计循环双端队列(暴力)
  10. Java实现 LeetCode 377 组合总和 Ⅳ