日期:2014-05-20  浏览次数:20718 次

关于 线程的yield()方法的 困惑,求调教!!!
首先,我看yield()在我书上是翻译成礼让。

那么假如一个线程如果执行了yield()方法,是暂停自己,100%去执行别的线程去?

还是说先暂停下自己,然后和所有线程再一起重新排队等待cpu资源?

如果是第一种,为什么我发现礼让一次,线程本身又重新执行;

如果是第二种,那yield()拿来做什么用,不是达不到“礼让”的目的么?



------解决方案--------------------
让当前这个线程希望放弃对CPU的占用,文档上说文档上还说调度器完全可以忽略这个“希望”而让当前线程继续占用CPU。看文档吧,哪里说的比较明白。
------解决方案--------------------
《Java Concurrency in Practice》12.1.6有这么一句话:

The effectiveness of this technique is platform-specific, since the JVM is free to treat THRead.yield as a no-op [JLS 17.9]; using a short but nonzero sleep would be slower but more reliable.) 


上面提到的JLS 17.9是这么写的:
Thread.sleep causes the currently executing thread to sleep (temporarily cease execution) for the specified duration, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors, and resumption of execution will depend on scheduling and the availability of processors on which to execute the thread.
Neither a sleep for a period of zero time nor a yield operation need have observable effects.

It is important to note that neither Thread.sleep nor Thread.yield have any synchronization semantics. In particular, the compiler does not have to flush writes cached in registers out to shared memory before a call to Thread.sleep or Thread.yield, nor does the compiler have to reload values cached in registers after a call to Thread.sleep or Thread.yield.
------解决方案--------------------
大家应该去看看操作系统 一个操作系统也就是一个虚拟机 虚拟机里面有很多很好的算法思想

比如线程的调度 (线程的调度不管最后怎么样,目的都是让CPU利用率最大化,不会让CPU闲着),这是一种效率最优的操作系统思想。在操作系统里面关于线程调度,线程A正在运行,需要调度线程B,指令集发出调用线程B的命令,这时候调用线程B肯定要调用很多必要的资源。在这段时间内,为了效率最优,线程A会一直运行,直到线程B所需的资源全部就绪才会给CPU资源让给线程B。这也是操作系统虚拟机的一种线程调度最优思想。想必JVM设计的时候也考虑到这一点,所以关于yield方法线程的调用也是这样的。(为了效率最优,线程A会一直运行,直到线程B所需的资源全部就绪才会给CPU资源让给线程B)

楼主可以做一个程序实验
定义线程A ThreadA{System.out.println("a");};定义线程B TrheadB{System.out.println("b");}

public static void main(){
ThreadA a=new ....;
THreadB b=new ....;
for(10){ 
a.start();//打印10次

a.yield();//线程a让步
a.sleep(300);//让线程a休眠300毫秒,为了让线程b所需资源被全部调用并被执行。
b.start();//执行线程b
}
如果不加让a休眠300毫秒,结果应该是a打印10以上,然后b运行。
加上休眠300毫秒时间,结果就是a打印10次,然后b运行。加上300毫秒,为了让线程b所需资源被全部调用就绪,准备被执行。
这个结果正好验证了上面所说的线程调度最优的算法思想。