您好,登錄后才能下訂單哦!
本篇文章為大家展示了怎么在java中利用多線程有序輸出ABC,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
方式1:利用synchronized
這種方式也就是使用java內置的monitor機制,配合wait和notifyAll,代碼如下:
(1)利用volatile做線程間資源的同步訪問,同時作為線程調度的標志;
(2)利用notifyAll來喚醒其他等待當前的monitor資源的線程;
public class ThreadOrderWithSync { private volatile int flag = 'A'; private final static Object LOCK = new Object(); Runnable a = () -> { while (true) { synchronized (LOCK) { if (flag == 'A' ) { System.out.println("A"); flag = 'B'; // let other thread race to get the monitor LOCK.notifyAll(); } else { try { LOCK.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }; Runnable b = () -> { while (true) { synchronized (LOCK) { if (flag == 'B' ) { System.out.println("B"); flag = 'C'; // let other thread race to get the monitor LOCK.notifyAll(); } else { try { LOCK.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }; Runnable c = () -> { while (true) { synchronized (LOCK) { if (flag == 'C' ) { System.out.println("C"); flag = 'A'; // let other thread race to get the monitor LOCK.notifyAll(); } else { try { LOCK.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }; public void runTest() { Thread ta = new Thread(a); Thread tb = new Thread(b); Thread tc = new Thread(c); ta.start(); tb.start(); tc.start(); } public static void main(String[] args) { ThreadOrderWithSync sync = new ThreadOrderWithSync(); sync.runTest(); } }
方式2:利用并發包ReentrantLock和Condition的鎖機制
上面方式1的synchronized機制,因為當前的所有線程都爭用同一個monitor資源,因此只能通過notifyAll來通知其他線程來加鎖,因此每次都會出現race condition,但是,通過ReentrantLock的Condition,我們可以精確控制,下一個該喚醒signal的線程是哪一個(因為我們知道執行的順序是A->B->C的循環),相比synchronized的機制,Condition機制可以更精細化線程的調度設計,代碼示例如下:
/** * @author xijin.zeng created on 2018/8/31 * Thrads runing order: A->B->C */ public class ThreadOrderWithCondition { private static final ReentrantLock LOCK = new ReentrantLock(); private static final Condition C_A = LOCK.newCondition(); private static final Condition C_B = LOCK.newCondition(); private static final Condition C_C = LOCK.newCondition(); /** * init for A to run first */ private volatile int flag = 'A'; Runnable a = () -> { while (true) { LOCK.lock(); if (flag == 'A') { System.out.println("A"); flag = 'B'; // signal B to run C_B.signal(); } else { try { // block and wait signal to invoke C_A.await(); } catch (InterruptedException e) { e.printStackTrace(); } } LOCK.unlock(); } }; Runnable b = () -> { while (true) { LOCK.lock(); if (flag == 'B') { System.out.println("B"); flag = 'C'; // signal C to run C_C.signal(); } else { try { // block and wait signal to invoke C_B.await(); } catch (InterruptedException e) { e.printStackTrace(); } } LOCK.unlock(); } }; Runnable c = () -> { while (true) { LOCK.lock(); if (flag == 'C') { System.out.println("C"); flag = 'A'; // signal A to run C_A.signal(); } else { try { // block and wait signal to invoke C_C.await(); } catch (InterruptedException e) { e.printStackTrace(); } } LOCK.unlock(); } }; public void runTest() { Thread threadA = new Thread(a); Thread threadB = new Thread(b); Thread threadC = new Thread(c); threadA.start(); threadB.start(); threadC.start(); } public static void main(String[] args) { ThreadOrderWithCondition o = new ThreadOrderWithCondition(); o.runTest(); } }
上述內容就是怎么在java中利用多線程有序輸出ABC,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。