1. 程式人生 > >三個執行緒依次順序執行

三個執行緒依次順序執行

保證三個執行緒依次按順序執行

在有一些需求的情況下,我們需要三個執行緒依次按順序執行,那麼有人就會問了,為什麼不把三個執行緒的run方法依次放到三個方法體中,然後依次執行,按順序呼叫三個方法體,這樣不是同樣達到了目的了麼,為什麼非要弄的那麼複雜,我個人的觀點是別人面試官不問的這樣深一點,怎麼能體現他的技術了。所以我就在網上找了幾篇blok,發現程式碼都有,不過都達不到目的,在這一篇blok中 [ 連結 ] 發現用到了join方法,不過經過測試,達不到想要的目的。廢話不多說,下面貼程式碼

 final Thread t1 = new Thread(new Runnable() {
            public
void run() { System.out.println(Thread.currentThread().getName() + " run 1"); } }, "T1"); final Thread t2 = new Thread(new Runnable() { public void run() { System.out.println(Thread.currentThread().getName() + " run 2"); try
{ t1.join(10); } catch (InterruptedException e) { e.printStackTrace(); } } }, "T2"); final Thread t3 = new Thread(new Runnable() { public void run() { System.out.println(Thread.currentThread().getName() + " run 3"
); try { t2.join(10); } catch (InterruptedException e) { e.printStackTrace(); } } }, "T3"); t1.start(); t2.start(); t3.start(); }

在這裡我在t2的執行緒裡面t1 的join方法,搶佔時間片,然後在t3的執行緒裡面,搶佔t2的時間片,理應是 t3執行>t2執行>t1執行,可以到最後結果的時候,每次的結果都不盡相同,這讓我很納悶,有興趣的同學可以嘗試一下。歡迎互相討論。

在這裡我就去翻看執行緒的文件,發現了newSingleThreadExecutor 這個執行緒池,保證執行緒裡面的任務依次執行,這讓我發現了新大陸,立馬實踐了一下,發現不負所望

public class TestJoin {
    public static void main(String[] args) throws InterruptedException {
        final Thread t1 = new Thread(new Runnable() {
            public void run() {
                System.out.println(Thread.currentThread().getName() + " run 1");
            }
        }, "T1");
        final Thread t2 = new Thread(new Runnable() {
            public void run() {
                System.out.println(Thread.currentThread().getName() + " run 2");
                try {
                    t1.join(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "T2");
        final Thread t3 = new Thread(new Runnable() {
            public void run() {
                System.out.println(Thread.currentThread().getName() + " run 3");
                try {
                    t2.join(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "T3");
        // method1
        //t1.start();
        //t2.start();
        //t3.start();

//        method 2 使用 單個任務的執行緒池來實現。保證執行緒的依次執行
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.submit(t1);
        executor.submit(t2);
        executor.submit(t3);
        executor.shutdown();
    }
}

在這裡發現結果每次都是 t1執行,t2執行,t3執行,這裡達到目的了之後,不禁回想,這個Single執行緒池為啥這麼好用,不由得就像把執行緒池狠狠的看一遍,然後就去翻看了原始碼

    /**
     * Creates an Executor that uses a single worker thread operating
     * off an unbounded queue. (Note however that if this single
     * thread terminates due to a failure during execution prior to
     * shutdown, a new one will take its place if needed to execute
     * subsequent tasks.)  Tasks are guaranteed to execute
     * sequentially, and no more than one task will be active at any
     * given time. Unlike the otherwise equivalent
     * {@code newFixedThreadPool(1)} the returned executor is
     * guaranteed not to be reconfigurable to use additional threads.
     *
     * @return the newly created single-threaded Executor
     */
    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

這個例項化的意思我嘗試翻譯了一下,意思就是建立一個只有一個執行緒的執行緒池來操作不限數量的佇列,也就是把執行緒放進了一個佇列中,佇列我們都知道是FIFO的。SingleThreadExecutor的工作執行緒只有一個,其他佇列中的執行緒都處於休眠,也就是sleep狀態,當這個worker執行緒做完事了,也就是run方法執行結束,就又從佇列中拿出一個休眠執行緒(sleep)出來喚醒(notify),這樣依次把佇列中的所有執行緒處理完畢,這樣並沒有結束,如果執行緒池中沒有待處理的執行緒,執行緒池一直會等待,等待下一次任務的提交,除非把執行緒池給shutdown掉,這樣執行緒池的生命週期才算完畢。

第一次寫部落格,希望大家多多關注,大家共同進步,我也瞻仰了許多大神寫的部落格,希望緊跟大神的腳步。
—小小程式設計師