join()介紹及三個線程順序輸出實現


一、join介紹

  Thead.join()函數在使用后,會掛起調用線程,直到被調用線程結束執行,調用線程才會繼續執行。源碼中調用join后,方法會一直檢測要join()的線程是否存活(isAlive()方法),直到線程執行完成后,調用線程的this.notifyAll()方法,才會回到剛剛掛起的主程序。基本操作如下:

public class Worker extends Thread {

    // 工作者名
    private String name;
    // 工作時間
    private long time;

    public Worker(String name, long time) {
        this.name = name;
        this.time = time;
    }

    @Override
    public void run() {
        // TODO 自動生成的方法存根
        try {        
            System.out.println(name + "開始工作");
     Thread.sleep(time);   
            System.out.println(name + "工作完成,耗費時間=" + time);
        } catch (InterruptedException e) {
            // TODO 自動生成的 catch 塊
            e.printStackTrace();
        }
    }

}

public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub
        Worker worker0 = new Worker("worker0", (long) (Math.random() * 1000));
        Worker worker1 = new Worker("worker1", (long) (Math.random() * 1000 + 1000));
        Worker worker2 = new Worker("worker2", (long) (Math.random() * 1000 + 2000));
        
        worker1.start();
        worker0.start();

        worker1.join();
        worker0.join();
        System.out.println("准備工作就緒");

        worker2.start();
    }

  結果如下:

 

二、join方式代碼實現

  有了上面的介紹很容易想到,三個線程順序輸出,讓他們依次join(),按順序等待執行就好了,代碼如下:

public static void main(String[] args) {
        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() {

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

        t1.start();
        t2.start();
        t3.start();
        
        //方法二
        // ExecutorService executor = Executors.newSingleThreadExecutor();
        // executor.submit(t1);
        // executor.submit(t2);
        // executor.submit(t3);
        // executor.shutdown();
    }

  效果如圖:

 

三、既然是多線程,自然也可以用加鎖的方式實現,直接上代碼:

package com.concurrency;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ThreeTheadPrintByOrder2_Lock {

    public static void main(String[] args) {
        new ThreadA().start();
        new ThreadB().start();
        new ThreadC().start();
    }

    private static Lock lock = new ReentrantLock();
    private static int state = 0;

    static class ThreadA extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 10;) {
                lock.lock();
                if (state % 3 == 0) {
                    System.out.println(Thread.currentThread().getName() + " A");
                    state++;
                    i++;
                }
                lock.unlock();
            }
        }
    }

    static class ThreadB extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 10;) {
                lock.lock();
                if (state % 3 == 1) {
                    System.out.println(Thread.currentThread().getName() + " B");
                    state++;
                    i++;
                }
                lock.unlock();
            }
        }
    }

    static class ThreadC extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 10;) {
                lock.lock();
                if (state % 3 == 2) {
                    System.out.println(Thread.currentThread().getName() + " C");
                    state++;
                    i++;
                }
                lock.unlock();
            }
        }
    }

}

  效果如下:

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM