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

一、线程休眠 sleep

sleep() 方法定义在Thread.java中,是 static 修饰的静态方法。

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

二、sleep示例

publicclassSleepTest{privatestaticObject obj =newObject();publicstaticvoid main(String[] args){Thread t1 =newMyThread(“t1”); t1.start();}staticclassMyThreadextendsThread{publicMyThread(String name){super(name);}publicvoid 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执行权的。

发表回复

您的电子邮箱地址不会被公开。