三個線程ABC,交替列印ABC_並發編程

來源:互聯網
上載者:User
synchronized

問題為三線程間的同步喚醒操作,主要的目的就是ThreadA->ThreadB->ThreadC→ThreadA……迴圈執行三個線程。為了控制線程執行的順序,那麼就必須要確定喚醒、等待的順序,所以每一個線程必須同時持有兩個對象鎖,才能繼續執行。一個對象鎖是prev,就是前一個線程所持有的對象鎖。還有一個就是自身對象鎖。

主要的思想就是,為了控制執行的順序,必須要先持有prev鎖,也就是前一個線程要釋放自身對象鎖,再去申請自身對象鎖,兩者兼備時列印字母,之後首先調用self.notifyAll()釋放自身對象鎖,喚醒下一個等待線程,再調用prev.wait()釋放prev對象鎖,終止當前線程,等待迴圈結束後再次被喚醒。程式啟動並執行主要過程就是A線程最先運行,持有C,A對象鎖,後釋放A,C鎖,喚醒B。線程B等待A鎖,再申請B鎖,後列印B,再釋放B,A鎖,喚醒C,線程C等待B鎖,再申請C鎖,後列印C,再釋放C,B鎖,喚醒A……

為了避免JVM啟動ThreadA、ThreadB、ThreadC三個線程順序的不確定性。需要讓A,B,C三個線程以確定的順序啟動,中間加一段sleep確保前一個線程已啟動。

public class ABC {    public static class ThreadPrinter implements Runnable {        private String name;        private Object prev;        private Object self;         private ThreadPrinter(String name, Object prev, Object self) {            this.name = name;            this.prev = prev;            this.self = self;        }         @Override        public void run() {            int count = 10;            while (count > 0) {//多線程並發,不能用if,必須用迴圈測試等待條件,避免虛假喚醒                synchronized (prev) {    // 先擷取 prev 鎖                    synchronized (self) {// 再擷取 self 鎖                        System.out.print(name);                        count--;                         self.notifyAll();// 先釋放 self,喚醒其他線程競爭self鎖                    }                    try {                        prev.wait();     // 再釋放 prev,休眠等待喚醒                        /**                         * 注意的是notify()調用後,並不是馬上就釋放對象鎖,而是在相應的synchronized(){}語句塊執行結束,自動釋放鎖,                         * JVM會在wait()對象鎖的線程中隨機選取一線程,賦予其對象鎖,喚醒線程,繼續執行。                         */                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }    }     public static void main(String[] args) throws Exception {        Object a = new Object();        Object b = new Object();        Object c = new Object();        ThreadPrinter pa = new ThreadPrinter("A", c, a);        ThreadPrinter pb = new ThreadPrinter("B", a, b);        ThreadPrinter pc = new ThreadPrinter("C", b, c);          new Thread(pa).start();        Thread.sleep(10);        new Thread(pb).start();        Thread.sleep(10);        new Thread(pc).start();        Thread.sleep(10);    }}
Lock
public class ABC_Lock {    private static Lock lock = new ReentrantLock();//通過JDK5中的Lock鎖來保證線程的訪問的互斥    private static int state = 0;     static class ThreadA extends Thread {        @Override        public void run() {            for (int i = 0; i < 10; ) {                try {                    lock.lock();                    while (state % 3 == 0) {//多線程並發,不能用if,必須用迴圈測試等待條件,避免虛假喚醒                        System.out.print("A");                        state++;                        i++;                    }                } finally {                    lock.unlock();// lock()和unlock()操作結合try/catch使用                }            }        }    }     static class ThreadB extends Thread {        @Override        public void run() {            for (int i = 0; i < 10; ) {                try {                    lock.lock();                    while (state % 3 == 1) {//多線程並發,不能用if,必須用迴圈測試等待條件,避免虛假喚醒                        System.out.print("B");                        state++;                        i++;                    }                } finally {                    lock.unlock();// lock()和unlock()操作結合try/catch使用                }            }        }    }     static class ThreadC extends Thread {        @Override        public void run() {            for (int i = 0; i < 10; ) {                try {                    lock.lock();                    while (state % 3 == 2) {//多線程並發,不能用if,必須用迴圈測試等待條件,避免虛假喚醒                        System.out.print("C");                        state++;                        i++;                    }                } finally {                    lock.unlock();// lock()和unlock()操作結合try/catch使用                }            }        }    }     public static void main(String[] args) {        new ThreadA().start();        new ThreadB().start();        new ThreadC().start();    }}
Condition
public class ABC_Condition {    private static Lock lock = new ReentrantLock();    private static Condition A = lock.newCondition();    private static Condition B = lock.newCondition();    private static Condition C = lock.newCondition();     private static int count = 0;     static class ThreadA extends Thread {        @Override        public void run() {            try {                lock.lock();                for (int i = 0; i < 10; i++) {                    while (count % 3 != 0)                        A.await(); // A釋放lock鎖                    System.out.print("A");                    count++;                    B.signal(); // A執行完喚醒B線程                }            } catch (InterruptedException e) {                e.printStackTrace();            } finally {                lock.unlock();            }        }    }     static class ThreadB extends Thread {        @Override        public void run() {            try {                lock.lock();                for (int i = 0; i < 10; i++) {                    while (count % 3 != 1)                        B.await();// B釋放lock鎖                    System.out.print("B");                    count++;                    C.signal();// B執行完喚醒C線程                }            } catch (InterruptedException e) {                e.printStackTrace();            } finally {                lock.unlock();            }        }    }     static class ThreadC extends Thread {        @Override        public void run() {            try {                lock.lock();                for (int i = 0; i < 10; i++) {                    while (count % 3 != 2)                        C.await();// C釋放lock鎖                    System.out.println("C");                    count++;                    A.signal();// C執行完喚醒A線程                }            } catch (InterruptedException e) {                e.printStackTrace();            } finally {                lock.unlock();            }        }    }     public static void main(String[] args) throws InterruptedException {        new ThreadA().start();        new ThreadB().start();        ThreadC threadC = new ThreadC();        threadC.start();        threadC.join();// main線程調用threadC.join(),會等threadC執行完成後,再執行main線程        System.out.println(count);    }}
Semaphore
public class ABC_Semaphore {    // 以A開始的訊號量,初始訊號量數量為1    private static Semaphore A = new Semaphore(1);    // B、C訊號量,A完成後開始,初始訊號數量為0    private static Semaphore B = new Semaphore(0);    private static Semaphore C = new Semaphore(0);     static class ThreadA extends Thread {        @Override        public void run() {            try {                for (int i = 0; i < 10; i++) {                    A.acquire();// A擷取訊號執行                    System.out.print("A");                    B.release();// B釋放訊號,B訊號量為1,可以執行                }            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }     static class ThreadB extends Thread {        @Override        public void run() {            try {                for (int i = 0; i < 10; i++) {                    B.acquire();                    System.out.print("B");                    C.release();                }            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }     static class ThreadC extends Thread {        @Override        public void run() {            try {                for (int i = 0; i < 10; i++) {                    C.acquire();                    System.out.println("C");                    A.release();                }            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }     public static void main(String[] args) throws InterruptedException {        new ThreadA().start();        new ThreadB().start();        new ThreadC().start();    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.