黑马程序员技术交流社区
标题:
sleep() 和yield()区别
[打印本页]
作者:
王丽
时间:
2011-7-27 06:18
标题:
sleep() 和yield()区别
线程中sleep() 和yield() 的区别是什么?什么情况用哪个方法更好?
作者:
匿名
时间:
2011-7-27 06:45
这俩个都是 Thread的方法
sleep(long millis, int nanos)
在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
yield()
暂停当前正在执行的线程对象,并执行其他线程。
作者:
王松朝
时间:
2011-7-27 08:25
yield()调用是安全的
但是没有机制保证会执行,只是一个标志,表示当前线程可以被切换
作者:
崔虎
时间:
2011-7-27 08:35
sleep()方法,使当前正在执行的线程,放弃CPU,而睡眠指定的时间。
范例1:sleep。[code=java]package org.cxy.demo;
public class Demo extends Thread{
public Demo(String name){
super(name);
}
public static void main(String[] args) {
Demo t1 = new Demo("小猫");
Demo t2 = new Demo("小鸟");
t1.start();
t2.start();
}
public void run(){
try {
System.out.println(Thread.currentThread().getName()+"说:我要进行秒睡!");
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName()+"说:睡了2秒醒了!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}[/code]当一个线程睡眠的时候,CPU会转去为其他线程服务去,程序执行的结果:[code=java]小鸟说:我要进行秒睡!
小猫说:我要进行秒睡!
// 注意,此处会等待2秒。然后输出之后的两句。
小猫说:睡了2秒醒了!
小鸟说:睡了2秒醒了![/code]因此,可以使用sleep方法,来完成线程间的切换(调度)。若在run方法中,没有使用Thread.sleep()方法,那么程序的执行结果,可能是这样的:[code=java]小猫说:我要进行秒睡!
小猫说:睡了2秒醒了!
小鸟说:我要进行秒睡!
小鸟说:睡了2秒醒了![/code]此时,这四句话的,被说出的顺序,就不太确定了。除了能保证“小猫说:我要进行秒睡!”将在“小猫说:睡了2秒醒了!”之前被打印出来,“小鸟说:我要进行秒睡!”在“小鸟说:睡了2秒醒了!”之前被打印出来,之外,其他的无法保证。
yield(),即线程让步。
范例2:yield。[code=java]package org.cxy.demo;
public class Demo extends Thread{
public Demo(String name){
super(name);
}
public static void main(String[] args) {
Demo t1 = new Demo("小猫");
Demo t2 = new Demo("小鸟");
t1.start();
t2.start();
}
public void run(){
System.out.println(Thread.currentThread().getName()+"说:我要进行秒睡!");
Thread.currentThread().yield();
System.out.println(Thread.currentThread().getName()+"说:睡了2秒醒了!");
}
}[/code]• 使用Thread类的静态方法yield() 进行让步操作。
• yield()方法使当前线程放弃本次抢到的CPU,回到就绪状态。从而使其他线程可以运行。但此方法同样没有任何保障。让步的线程可能再次被选中。
• 此方法不能保证做太多的事,尽管通常它会使当前线程回到就绪状态,并使具有相同优先级的线程能够有机会运行。
• 强烈提示:如果你的一些高优先级的线程很少发生阻塞,那么你的低优先级的线程可能永远都运行不了。
因此,他们二人都可以使线程放弃当前的cpu。 sleep可以让线程在放弃cpu后,有一段时间内不能参与cpu的竞争。而yield方法,仅仅是进行简单的线程让步,但是让步的线程可能再次被选中。
另外,提示一下,当在同步方法中,使某个线程调用了sleep方法,则该线程不会释放锁。
[
本帖最后由 崔虎 于 2011-07-27 08:37 编辑
]
作者:
匿名
时间:
2011-7-27 09:00
sleep ()方法使当前运行中的线程睡眼一段时间,进入不可运行状态,这段时间的长短是由程序设定的,yield ()方法使当前线程让出CPU占有权,但让出的时间是不可设定的。
作者:
匿名
时间:
2011-7-27 09:08
[size=3]sleep()方法是自行休眠,把cpu让给优先级别比其低的线程,当到了限定的时间后 该线程进入运行状态。[/size]
[size=3]
[/size]
[size=3]yield()是使具有与当前线程相同优先级别相同的线程有运行的机会。如果有其他的线程与当前线程有相同的优先级并且是可运行的。该方法将被调入到可运行线程池,并允许其他线程运行。如果没有相同优先级的线程是Runnable状态。那么该方法什么也不做,即该线程将继续运行。[/size]
作者:
匿名
时间:
2011-7-27 10:18
:lol 虎哥回答的入情入理
[color=Red]sleep方法和yield方法的区别[/color]
1、sleep方法暂停当前的线程后,会给其他的线程执行的机会,不会理会其他线程的优先级,但是yield方法只会给优先级相同,或者优先级更高的线程执行的机会
2、sleep方法会将线程转入阻塞状态,知道经过阻塞时间才会转入就绪状态,而yield方法不会讲线程转入阻塞状态,它只是强制当前线程进入就绪状态,因此完全有可能某个线程调用yield 方法暂停之后,这个线程又立即获得处理器资源执行。
3、sleep方法声明抛出了interruptedException异常,所以调用sleep方法时候要么捕捉这个异常,要么显示声明抛出这个异常,而yield方法则没有声明抛出任何异常
4、sleep方法比yield方法有更好的可移植性,通常不需要依靠yield来控制并发线程的执行
如下两个程序简单说明两个方法的用法:
[color=Red]线程睡眠:sleep[/color][code=java]package cn.itcast.heima
import java.util.*;
public class TestSleep
{
public static void main(String[] args) throws Exception
{
for (int i = 0; i < 10 ; i++ )
{
System.out.println("当前时间: " + new Date());
//调用sleep方法让当前线程暂停1s。
Thread.sleep(1000);
}
}
}[/code][color=Blue]这个程序可看出程序结果两条字符串之间时间间隔为1秒[/color]
[color=Red]
线程让步:yield[/color][code=java]package cn.itcast.heima
public class TestYield extends Thread
{
public TestYield()
{
}
public TestYield(String name)
{
super(name);
}
//定义run方法作为线程执行体
public void run()
{
for (int i = 0; i < 50 ; i++ )
{
System.out.println(getName() + " " + i);
//当i等于20时,使用yield方法让当前线程让步
if (i == 20)
{
Thread.yield();
}
}
}
public static void main(String[] args) throws Exception
{
//启动两条并发线程
TestYield ty1 = new TestYield("高级");
//将ty1线程设置成最高优先级
ty1.setPriority(Thread.MAX_PRIORITY);
ty1.start();
TestYield ty2 = new TestYield("低级");
//将ty1线程设置成最低优先级
ty2.setPriority(Thread.MIN_PRIORITY);
ty2.start();
}
}[/code]上面程序run方法调用yield方法让线程暂停,让系统线程调度器重新调度,当后面[code=java]ty1.setPriority(Thread.MAX_PRIORITY);
ty2.setPriority(Thread.MIN_PRIORITY);[/code]、
[color=Blue]注释的时候,--也就是两条线程的优先级一样,所以其中一条线程使用yield方法站台,另外一条线程就会执行,
如果我们不注释上面两个代码,那么可以看到当一条线程调用yield方法之后又马上获得了执行的机会[/color]
作者:
匿名
时间:
2011-7-27 10:19
1) sleep()使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会执行;yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。
2) sleep()可使优先级低的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会;yield()只能使同优先级的线程有执行的机会。
class TestThreadMethod extends Thread{
public static int shareVar = 0;
public TestThreadMethod(String name){
super(name);
}
public void run(){
for(int i=0; i<4; i++){
System.out.print(Thread.currentThread().getName());
System.out.println(" : " + i);
//Thread.yield(); (1)
/* (2) */
try{
Thread.sleep(3000);
}
catch(InterruptedException e){
System.out.println("Interrupted");
}}}
}
public class TestThread{
public static void main(String[] args){
TestThreadMethod t1 = new TestThreadMethod("t1");
TestThreadMethod t2 = new TestThreadMethod("t2");
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
}
}
运行结果为:
t1 : 0
t1 : 1
t2 : 0
t1 : 2
t2 : 1
t1 : 3
t2 : 2
t2 : 3
由结果可见,通过sleep()可使优先级较低的线程有执行的机会。注释掉代码(2),并去掉代码(1)的注释,结果为:
t1 : 0
t1 : 1
t1 : 2
t1 : 3
t2 : 0
t2 : 1
t2 : 2
t2 : 3
可见,调用yield(),不同优先级的线程永远不会得到执行机会。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2