首先,我看yield()在我书上是翻译成礼让。那么假如一个线程如果执行了yield()方法,是暂停自己,100%去执行别的线程去?还是说先暂停下自己,然后和所有线程再一起重新排队等待cpu资源?如果是第一种,为什么我发现礼让一次,线程本身又重新执行;如果是第二种,那yield()拿来做什么用,不是达不到“礼让”的目的么?

解决方案 »

  1.   

    让当前这个线程希望放弃对CPU的占用,文档上说文档上还说调度器完全可以忽略这个“希望”而让当前线程继续占用CPU。看文档吧,哪里说的比较明白。
      

  2.   


    class MyThread implements Runnable{
    public void run(){
    for(int i=0;i<8;i++){
    if (i==4){ //如果i==4,则进行礼让一次
    System.out.println(Thread.currentThread().getName()+"进行了礼让一次"+"-->"+i);
    Thread.currentThread().yield();//进行礼让
    }
    System.out.println("执行"+Thread.currentThread().getName()+"-->"+i);

    }
    }
    }
    public class P292_1{
    public static void main(String args[]){
    Thread th1=new Thread(new MyThread(),"线程A");
    Thread th2=new Thread(new MyThread(),"线程B");
    th1.start();
    th2.start();

    }
    }
      

  3.   

    LZ啊,这个方法正式代码里一般不要用因为jvm并不保证该方法有效
      

  4.   

    《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.
      

  5.   

    大家应该去看看操作系统 一个操作系统也就是一个虚拟机 虚拟机里面有很多很好的算法思想比如线程的调度 (线程的调度不管最后怎么样,目的都是让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所需资源被全部调用就绪,准备被执行。
    这个结果正好验证了上面所说的线程调度最优的算法思想。
      

  6.   

    打的字有点多哪 反正就是一句话,加上上面那个例子。线程调度最优算法思想:为了效率最优,线程A会一直运行,直到线程B所需的资源全部就绪才会给CPU资源让给线程B
      

  7.   

    class ThreadA implements Runnable{
    public void run(){
    for(int i=0;i<50;i++){
    System.out.println("执行a线程");
    }
    }
    }
    class ThreadB implements Runnable{
    public void run(){
    for(int i=0;i<50;i++){
    System.out.println("执行b线程");
    }
    }

    }
    class P292_2{
    public static void main(String args[]){
    Thread a=new Thread(new ThreadA(),"线程A");
    Thread b=new Thread(new ThreadB(),"线程B");

    a.start();
    a.yield();//线程a让步
    try{
    a.sleep(300); }catch(Exception e){}
    b.start();



    }
    }
      

  8.   

    JLS SE7版本中移除了JLS第三版中的那句话,原因在于:
    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6584700
    不过新版API关于yield的描述更加详细:http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#yield()
    public static void yield()
    A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint.
    Yield is a heuristic attempt to improve relative progression between threads that would otherwise over-utilise a CPU. Its use should be combined with detailed profiling and benching to ensure that it actually has the desired effect.It is rarely appropriate to use this method. It may be useful for debugging or testing purposes, where it may help to reproduce bugs due to race conditions. It may also be useful when designing concurrency control constructs such as the ones in the java.util.concurrent.locks package.
      

  9.   

    好吧,总体意思就是jdk1.6及之前的yield方法的API描述是不详细的,在jdk1.7的API中做了修正,jdk1.7 javadoc关于yield方法的描述如下:A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint.Yield is a heuristic attempt to improve relative progression between threads that would otherwise over-utilise a CPU. Its use should be combined with detailed profiling and benching to ensure that it actually has the desired effect.It is rarely appropriate to use this method. It may be useful for debugging or testing purposes, where it may help to reproduce bugs due to race conditions. It may also be useful when designing concurrency control constructs such as the ones in the java.util.concurrent.locks package.由之前的一句话变成好几段,信息丰富的,也清楚明了了。这里你只需看第一段即可,翻译如下:
    暗示调度器当前线程想让出正在使用的处理器。调度器可自由地忽略这种暗示。
    -----------------------
    如同System.gc方法一样,暗示jvm要进行垃圾回收了,但jvm可以不理你
      

  10.   

    还有最后一段的第一句话也很重要:It is rarely appropriate to use this method极少有要使用这个方法的时候
      

  11.   


    谢谢了。我明白了。
    暗示调度器当前线程想让出正在使用的处理器。调度器可自由地忽略这种暗示。
    也就是说。用yield()让出了资源。并不是100%就让别的进程去使用资源。很有可能自己礼让了。下一次使用资源的仍然是自己。对吧。