簡體   English   中英

從多個線程修改數組

[英]Modifing an array from multiple threads

所以我有一個線程,用另一個隨機char替換char數組中最小的char。 線程運行直到數組僅包含“ z”。 但是,當我創建多個線程時,我得到了奇怪的輸出,並且想知道它是否是打印的唯一問題,或者我的代碼是否確實不正確。

我線程中的run()方法:

public void run() {
    char[] expected = { 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z' };
    while (timesModified < 100 && !Arrays.equals(array, expected)) {
        try {
            array[findMinIndex(array)] = rndChar();
            timesModified++;
            Thread.sleep(2000);
            for (char c : array) {
                System.out.print(c + " ");
            }
            System.out.println();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

我的主要:

public static void main(String[] args) {
        char[] sa_table = new char[10];
        Arrays.fill(sa_table, 'a');
        Thread t = new Thread(new AddToTable(sa_table));
        Thread t1 = new Thread(new AddToTable(sa_table));
        Thread t2 = new Thread(new AddToTable(sa_table));
        t.start();
        t1.start();
        t2.start();
        try {
            t.join();
            t1.join();
            t2.join();
        } catch (Exception e) {
            System.out.println("Interrupted");
        }
    }

控制台輸出:

n n n a a a a a a a a a a a a a a a a a a a a a 
a a a a a a 

n u U a n u U a a a a a a a 
a a a a a a 
n u N a a a a a a a 
n n u o a a a a a a a 
u o K a a a a a a 
n u o i a a a a a a 
n u o i A a a a a a 
n u o i A a a a a a 
n u o i G a a a a a 
n u o i K a a a a a 
n u o i u a a a a a 
n u o i u s a a a a 
n u o i u s x a a a 
n n n u o i u s u o i u s x l a a 
u o i u s x l D a 
x l h a 
n u o i u s x l h H 
n u o i u s x l h D 
n u o i u s x l h a 
n u o i u s x l h r 
n u o i u s x l R r 
n u o i u s x l v r 
n u o C u s x l v r 
n u o b u s x l v r 
n n u o S u s x l v r 
u o D u s x l v r 
n u o T u s x l v r 
n u o l u s x l v r 
n u o M u s x l v r 
n u o M u s x l v r 
n u o t u s x l v r 
n u o t u s x m v r 
n u o t u s x J v r 
n u o t u s x R v r 
n u o t u s x i v r 
n u o t u s x t v r 
F u o t u s x t v r 
A u o t u s x t v r 
D u o t u s x t v r 
l u o t u s x t v r 
e u o t u s x t v r 
L u o t u s x t v r 
L u o t u s x t v r 
o u o t u s x t v r 
m u o t u s x t v r 
s u o t u s x t v r 
s u C t u s x t v r 
s u D t u s x t v r 
s u q t u s x t v r 
s u W t u s x t v r 
s u Y t u s x t v r 
s u C t u s x t v r 
s u s t u s x t v r 
s u s t u s x t v h 
s u s t u s x t v D 
s u s t u s x t v w 
I u s t u s x t v w 
c u s t u s x t v w 
g u s t u s x t v w 
b u s t u s x t v w 
N u s t u s x t v w 
O u s t u s x t v w 
u u s t u s x t v w 
u u E t u s x t v w 
u u u u C t u s x t v w 
u T u T t u s x t v w 
t u s x t v w 
u u u X t u s x t v w u X t u s x t v w 

u u D t u s x t v w 
u u u T t u s x t v w 
u u X t u s x t v w 
u e t u s x t v w 
u u f t u s x t v w 
u u C t u s x t v w 
u u u t u s x t v w 
u u u t u o x t v w 
u u u t u i x t v w 
u u u t u P x t v w 
u u u t u v x t v w 
u u u b u v x t v w 
u u u u u u K u v x t v w 
u u u x u v x t v w 
x u v x K v w 
u u u x u v x W v w 
u u u x u v x c v w 
u u u u u x u v x e v w 
u u u u x u v x n v w 
u u u x u v x q v w 
x u v x T v w 
u u u x u v x w v w 
z u u x u v x w v w 
z P u x u v x w v w 
z T u x u v x w v w 
z z b u x u v x w v w b u x u v x w v w 

z p u x u v x z p u x u v x w v w 
w v w 

如您所見,輸出通常具有不同的長度,我不確定是什么原因導致的

您的問題來自這里:

  for (char c : array) {
       System.out.print(c + " ");
  }
  System.out.println();

該循環可以在一個線程的中間暫停,而在另一個線程中啟動,因此可以在調用println()之前先打印兩個混合的線程。

例如,當您擁有:

n n u o S u s x l v r 
u o D u s x l v r 

這意味着您擁有以下字符串: nuo S usxlvr ,一個線程開始打印它,它打印了n ,然后另一個接管了,打印了所有內容-> nnuo S usxlvr + a \\nprintln() ),然后是第一個結束了他的工作,然后打印了其余的文件: uo D usxlvr

您似乎在這里面臨“互斥排除”或“互斥”問題:

https://zh.wikipedia.org/wiki/互斥

您必須確保不同時由多個線程編輯該數組。

無需查看代碼來檢查其是否正確執行了實際任務,對長度變化的答案很簡單:三個線程同時打印出值,因此您不知道哪個線程打印出哪個值。

例如,這些行:

u u u u C t u s x t v w 
u T u T t u s x t v w 
t u s x t v w 

由三個線程打印。 這就是值總數正確,換行次數(3)正確的原因。 嘗試以一種包含每個值的線程ID的方式進行打印,您會看到每次線程沒有獲得一行,而是每個參與線程的值和換行符混合在一起。

為避免這種情況,您可以使用StringBuilder匯編每個線程的值,然后一次性打印出來。

嘗試這個:

    public void run() {
    char[] expected = { 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z' };
    while (timesModified < 100 && !Arrays.equals(array, expected)) {
        try {
            array[findMinIndex(array)] = rndChar();
            timesModified++;
            Thread.sleep(2000);
            StringBuilder sb = new StringBuilder();
            for (char c : array) {
                sb.append(c + " ");
            }
            System.out.println(sb);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

暫無
暫無

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

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