A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 彭盼 中级黑马   /  2012-6-29 09:36  /  2761 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 彭盼 于 2012-6-29 09:39 编辑

package cn.pengpan.test;
public class YieldTest extends Thread{
        private int i;
        public YieldTest(){}
        public YieldTest(String name){
                super(name);
        }
        public void run(){
                for(;i < 10;i++){
                        System.out.println(Thread.currentThread().getName() + "---->" + i);
                        if(i == 5){
                                Thread.yield();
                        }
                }
        }
        public static void main(String[] args) {
                YieldTest yt2 = new YieldTest("优先级为10的线程开始运行了");
                yt2.setPriority(10);
                yt2.start();
                YieldTest yt1 = new YieldTest("优先级为1的线程开始运行了");
                yt1.setPriority(1);
                yt1.start();
        }
}
后来执行的结果是前10个I都是优先级为10的线程在执行
后10个i都是优先级为1的线程在执行
为什么两个线程并没有象预期的一样交替执行呢?照代码的意思
应该是优先级为10的线程执行到i=5时就放弃线程的,然后i=6后
就应该是优先级为1的线程从头开始执行的

点评

可行的正确优先级调度方案是,你可以用一个线程来识别其他线程的优先级,之后进行按优先级的run方法调用,而非java本身的线程调度  发表于 2012-6-29 11:56

6 个回复

倒序浏览
我运行的时候是交替的,
回复 使用道具 举报
楼主应该吧Thread.yield()理解成终止线程了吧,其实不是这样的,为了不让某线程独占资源,可以让该线程“休息”一下后转到到可执行状态,以便让具有相同优先级的线程进入执行状态。但也不是绝对的,就像楼主这个例子,优先级为10的进程 只有一个,即 yt2,所以当调用Thread.yield()之后还是 yt2执行。依次循环十次。yt2执行完之后yt1也执行十次。所以出现了上述结果
回复 使用道具 举报
本帖最后由 曾_强 于 2012-6-29 10:28 编辑

线程的优先级将该线程的重要性传递给调度器。调度器会优先让优先权最高的线程先执行,然而这并不意味着优先权较低的得不到运行。只是频率较低。

在绝大多数时间里,所有线程都是按默认优先级运行,试图操作线程优先级通常是一种错误。我理解的设置优先级只是自我安慰。让它多执行几次。不知道实际应用中的情况。

另外  yt2.setPriority(10);这样的方法  yt2.setPriority(MAX_PRIORITY);会更好。

调用 yield()只是建议CPU去执行其他线程而已。让当前线程释放执行权。
按照thinking In Java里面的意思是,这只是一个暗示而已,没有任何机制保证它将会被CPU采纳。当调用 yield()时,你也是在建议具有相同优先级的其他线程可以运行。

加同步才是最好的解决办法。

点评

如果要是你自己模拟线程环境,实现一个真实的权限机制呢?  发表于 2012-6-29 13:21

评分

参与人数 1技术分 +1 收起 理由
刘蕴学 + 1

查看全部评分

回复 使用道具 举报
这正好说明一个问题:yield()方法,并不是能确切让当前线程进入等待或者休眠状态的方法。它只是让当前线程稍微暂停了一下。有资料说是把运行状态切换到可运行状态。然后就把执行权暂时让给相同优先级的另一个处于可运行状态的线程。
你可以自己测试下,把两个线程设置为相同优先级,是可以看到交替的效果的,(但是,因为print()方法调用系统功能打印,也会出现延迟,我们看到的并不是严格的交替~!)
测试的结论是:yield()方法的效果,还要考虑线程的优先级priority,属于同一个优先级的线程才有资格交替。
回复 使用道具 举报
呵呵,书上都这么说,不过计算机可不太听我们的话!
回复 使用道具 举报
孙飞 中级黑马 2012-6-30 07:25:19
7#
我运行的结果是正确的啊,优先级高的不是说一定要先把它执行完才能执行低的,只不过它抢到cpu执行权的机率大一些而已,yield()是在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。也就是说,并不一定会一定切换线程,因为你yt2的优先级高,所以会有可能,yield方法让它短暂暂停后调度程序还会选 中它,所以yield方法在优先级相同的线程之间会更明显吧
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马