簡體   English   中英

可以創建一個由多個線程共享的for循環嗎?

[英]Possible to create a for loop shared by several threads?

我正在嘗試創建一個程序,該程序將為每個線程提供一個整數,然后該線程將使用該整數計算給定的代碼,然后返回以獲取另一個整數。 這將繼續進行,直到計算出所需計算的所有整數為止。

由於我對多線程並不真正有經驗,因此我不確定一旦完成第一個任務后如何使用一個線程並更改其工作。

當前,這是我創建和執行線程的方式:

public static void main(String[] args){
    ComputableInteger a = new ComputableInteger(1);
    ComputableInteger b = new ComputableInteger(2);
    ComputableInteger c = new ComputableInteger(3);
    Thread t1 = new Thread(a);
    Thread t2 = new Thread(b);
    Thread t3 = new Thread(c);
    t1.start();
    t2.start();
    t3.start();
}

現在,這可以正常工作,但是它只計算3個已經確定的整數。 我希望能夠選擇必須計算的整數個數,並且線程應始終僅取該行中的第一個空閑數。 因此,例如,我不想僅將前10個整數分配給t1,將后10個整數分配給t2,依此類推。 相反,我希望第一個線程完成處理,以獲取行中的下一個整數(在這種情況下為4)。

我一直在尋找threadPools,但是我也無法使它工作。 希望你們中的一些技巧!

編輯:

好的,所以我嘗試在同步打開的情況下實現getNext,這就是我的run函數的樣子:

public void run() {
    while (Executer.getNext() < 20) {
        if(computeInteger(number)) {
            Executer.incrementCount();
        }
        number = Executer.getNext();
    }
}

希望它可以檢查最多19個單個整數。這樣做是可以的,但是它設法跳過了一些數字,並且看到我已經同步了,所以我不確定如何解決這個問題。

編輯:

我切換到ExecuterService來解決此問題,但是在如何正確執行它方面存在一些問題:

public static void main(String[] args){
    final long startTime = System.currentTimeMillis();
    executorService.execute(new Runnable() {
        public void run() {
            int currentNumber;
            while ((currentNumber = Executer.getNext()) <= 10000000) {
                if(Executer.computeInteger(currentNumber)) {
                    Executer.incrementCount();
                }
            }
        }
    });

從我所看到的當前問題是,第一個線程是執行所有代碼的那個線程。 但是,如果我想將其分成一個線程進行1次迭代,而所有其他線程都同步運行,該如何處理呢?

使用ExecutorService類創建一個固定大小的線程池。 將您的計算邏輯放入可運行的類中。 遍歷for循環中的所有整數值,並在每次迭代時通過傳遞要在其上執行計算的數據並將其提交到ExecutorService線程池來創建可運行對象。

制作一個只能通過同步getter訪問的靜態字段。

private static int next = 1;

public static synchronized int getNext() {
    return next++;
}

在線程中,每當您需要一個新數字時都調用此方法!

編輯: getNext()方法已經增加了計數器,因此您只需調用一次即可:

public void run() {
    while ((number = Executer.getNext()) < 20) {
        // Do whatever you have to do with number
        // but don't increment the next counter anymore
    }
}

如果您不想使用Executor服務,也可以使用java 8 new stream api:

public static void main(String[] args) {

    List<Integer> integerToTreat = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);

    long start = System.currentTimeMillis();
    integerToTreat.parallelStream().forEach(i -> {
        // do your work here. For this example, just sleeping 1sec.
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    });
    System.out.println("Finished treating " + integerToTreat.size() + " items in " + (System.currentTimeMillis() - start) + " ms");
}

將輸出: Finished treating 8 items in 2068 ms

這樣,您將無法選擇線程數或線程池。 它使用的是由使用此api的所有循環共享的固定循環,其中包含的線程數與cpu中具有內核的線程數相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM