LeetCode:打印零與奇偶數【1116】


LeetCode:打印零與奇偶數【1116】

題目描述

假設有這么一個類:

class ZeroEvenOdd {
    public ZeroEvenOdd(int n) { ... }  // 構造函數
    public void zero(printNumber) { ... } // 僅打印出 0
    public void even(printNumber) { ... } // 僅打印出 偶數
    public void odd(printNumber) { ... } // 僅打印出 奇數
}


相同的一個 ZeroEvenOdd 類實例將會傳遞給三個不同的線程:

  • 線程 A 將調用 zero(),它只輸出 0 。
  • 線程 B 將調用 even(),它只輸出偶數。
  • 線程 C 將調用 odd(),它只輸出奇數。

每個線程都有一個 printNumber 方法來輸出一個整數。請修改給出的代碼以輸出整數序列 010203040506... ,其中序列的長度必須為 2n。

示例 1:

輸入:n = 2
輸出:"0102"
說明:三條線程異步執行,其中一個調用 zero(),另一個線程調用 even(),最后一個線程調用odd()。正確的輸出為 "0102"。
示例 2:

輸入:n = 5
輸出:"0102030405"

題目分析

  我們在1115題的時候已經說明,如果線程之間存在前驅關系的話可以用信號量來解決。我們先分析以下線程間的執行順序:

  [打印0]——>[打印奇數]——>[打印0]——>[打印偶數]——>...

  可見,結果是2*n個數字,其中有n個零,剩下的就是奇數和偶數對半。於本題來說打印0是優先分配資源進行執行的,打印奇數和偶數都是受限制的。優先執行的結束后釋放受限執行的線程的資源,受限線程才可繼續執行,所以設置odd和even的資源初始值(即信號量)為0,每當零打印完成后,按照打印順序為受限線程釋放資源。odd和even執行完成后,需要釋放打印零的資源,使得循環繼續。

  一定要理解信號量,這是多線程編程的關鍵!!!

Java題解

import java.util.concurrent.*;

class ZeroEvenOdd {
    private int n;
    private Semaphore s,s1,s2;
    
    
    public ZeroEvenOdd(int n) {
        this.n = n;
        s = new Semaphore(1);
        s1 = new Semaphore(0);
        s2 = new Semaphore(0);
    }

    // printNumber.accept(x) outputs "x", where x is an integer.
    public void zero(IntConsumer printNumber) throws InterruptedException {
        for(int i=1;i<=n;i++)
        {
            s.acquire();
            printNumber.accept(0);
            if((i&1) == 0)
                s1.release();
            else
                s2.release();
        }
    }

    public void even(IntConsumer printNumber) throws InterruptedException {
        for(int i=2;i<=n;i+=2)
        {
            s1.acquire();
            printNumber.accept(i);
            s.release();
        }
    }

    public void odd(IntConsumer printNumber) throws InterruptedException {
       for(int i=1;i<=n;i+=2)
        {
            s2.acquire();
            printNumber.accept(i);
            s.release();
        }
    }
}

  

 


免責聲明!

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



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