Java Thread.yield詳解

  這是Java中的一種線程讓步方法,讓Java中的線程從執行狀態變成就緒狀態,而後處理器再從就緒隊列中挑選線程進行執行(優先級大的,被挑選的機率較大),這種轉換也不肯定,讓或者不讓都是取決與處理器,線程可能繼續佔有處理器。java

**
     * 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.
     *
     * <p> 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 benchmarking to
     * ensure that it actually has the desired effect.
     *
     * <p> 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
     * {@link java.util.concurrent.locks} package.
     */
  //暗示調度器讓當前線程讓出佔用的處理器,可是讓或者是不讓,都是調度器本身決定的,有可能調用此方法事後,線程依然佔用處理器
    public static native void yield();

  看《Java併發編程藝術》這本書,裏面有用到Thread.yield方法,來測試Java線程優先級,代碼以下:編程

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class Priority {
    private static volatile boolean notStart=true;
    private static volatile boolean notEnd=true;

    public static void main(String[] argvs) throws Exception{
        List<Job> jobs=new ArrayList<Job>();
        for(int i=0;i<10;i++){
            int priority=i<5?Thread.MIN_PRIORITY:Thread.MAX_PRIORITY;
            Job job=new Job(priority);
            jobs.add(job);
            Thread thread=new Thread(job,"Thread:"+i);
            thread.setPriority(priority);
            thread.start();
        }
        notStart=false;
        TimeUnit.SECONDS.sleep(10);
        notEnd=false;

        for(Job job:jobs){
            System.out.println("Job Priority:"+job.priority+", Count: "+job.jobCount);
        }
    }

    static class Job implements Runnable{
        private int priority;
        private long jobCount;

        public Job(int priority){
            this.priority=priority;
        }

        @Override
        public void run() {
            while(notStart){
                Thread.yield();
            }
            while(notEnd){
                Thread.yield();
                jobCount++;
            }
        }
    }
}

  跑出結果以下:併發

Job Priority:1, Count: 6087836
Job Priority:1, Count: 6573345
Job Priority:1, Count: 6024024
Job Priority:1, Count: 6606573
Job Priority:1, Count: 6901572
Job Priority:10, Count: 6118724
Job Priority:10, Count: 5968747
Job Priority:10, Count: 5939391
Job Priority:10, Count: 6206129
Job Priority:10, Count: 6187854

 發現即便線程優先級爲1和爲10的線程,最後獲取CPU的次數是差很少的,沒有明顯差距,線程優先級沒有生效。程序的正確性不能依賴於線程的優先級。app

相關文章
相關標籤/搜索