簡體   English   中英

信號量問題:從並行線程訪問線程變量

[英]Semaphore Question: Accessing Thread Variable From A Parallel Thread

我正在嘗試了解 Java 中的信號量,並且我想使用並行線程在數組中同時生成數字並使用該數據執行操作而不改變數組本身以避免競爭條件。 在第一個線程中生成數字很簡單,如果程序連續運行,生成后獲取數據也不會太難。 但是,我不太明白如何在生成數組時從另一個線程訪問它。 我知道信號量旨在用於控制對共享數據結構的訪問,類似於互斥鎖,我不清楚的是如何以合法的方式聲明(在這種情況下為數組)。

這是一個基本示例:

import java.util.concurrent.Semaphore;
import java.util.Random;

public class Main {
    static Semaphore semaphore = new Semaphore(2);

    static class Thread1 extends Thread {
        private int[] randArray = new int[50];

        public void run() {
            try {
                Random rng = new Random();
                semaphore.acquire();

                try {
                    for (int i = 0; i < 50; i++) {
                        randArray[i] = rng.nextInt() % 100;
                        System.out.println("Random number " + i + " : " + randArray[i]);

                        Thread.sleep(2000);
                    }
                } finally {
                    semaphore.release();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    static class Thread2 extends Thread {

        public void run() {
            try {
                semaphore.acquire();
                try {
                    for (int i = 0; i < 50; i++) {
                        // calculate something using array generated in Thread1

                        Thread.sleep(2000);
                    }
                } finally {
                    semaphore.release();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Thread1 t1 = new Thread1();
        t1.start();
        Thread2 t2 = new Thread2();
        t2.start();
    }
}

創建空信號量。 啟動兩個線程。 每次 Thread1 加載一個數組索引時,發布一個信號量單元。 在線程 2 中,在處理索引之前等待循環中的信號量。

擺脫睡眠電話。

好吧,首先這里沒有共享數據結構,數組屬於 Thread-1,僅此而已。

其次 - 信號量不適合這個用例。 如果我理解正確,您希望在元素生成后立即進行 1 x 1 處理。 信號量可以像在您的代碼中一樣使用,但您將完全依靠運氣,Thread-1 總是做他的事情,而 Thread-2 緊隨其后 - 在現實生活中不會發生。 這只是程序的流程,不考慮內存一致性錯誤。 這可以重寫為對每個元素使用信號量,但在我看來這太混亂了。

信號量基本上就像現代 COVID-19 時代的商店——一次只能有 5 個人在商店里。 當一個人走進它就像semaphore.acquire() ,當一個人走出時 - semaphore.release() 如果有人想進入而商店里沒有足夠的空間 - 他會等待下一個人離開( semaphore.acquire()等到semaphore.release() )。

基本上,如果你真的很頑固,你可以使用原子類(如 AtomicInteger)、鎖甚至信號量來編寫這個程序,它看起來可以工作(並且在大多數情況下可以),但它會有與 Java 內存相關的細微錯誤模型(線程 1 寫入和線程 2 未看到更改),除非您知道自己在做什么。 我建議使用java.util.concurrent一些結構——比如AtomicIntegerArray。

暫無
暫無

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

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