![](/img/trans.png)
[英]Why this iOS implemtation of DesEncrypter doesn't produce the same result as Java?
[英]Mutiple Threads: the application doesn't produce same result every time
因此,在這里我編寫了三個簡單的類來檢查多個線程在Java中的工作方式,但是每次運行它們都會產生不同的結果。 這是代碼:
public class Accum {
private static Accum a = new Accum();
private int counter = 0;
private Accum(){}
public static Accum getAccum(){
return a;
}
public void updateCounter(int add){
counter+=add;
}
public int getCount(){
return counter;
}
}//end of class
public class ThreadOne implements Runnable {
Accum a = Accum.getAccum();
public void run() {
for(int x=0; x<98; x++){
//System.out.println("Counter in TWO "+a.getCount());
a.updateCounter(1000);
try{
Thread.sleep(50);
}catch(InterruptedException ex){}
}
System.out.println("one " + a.getCount());
}
}//end of class
public class ThreadTwo implements Runnable{
Accum a = Accum.getAccum();
public void run() {
for(int x=0; x<99; x++){
//System.out.println("counter in Two "+a.getCount());
a.updateCounter(1);
try{
Thread.sleep(50);
}catch(InterruptedException ex){}
}
System.out.println("two "+a.getCount());
}
public class TestThreaad {
public static void main(String[]args){
ThreadOne t1 = new ThreadOne();
ThreadTwo t2 = new ThreadTwo();
Thread one = new Thread(t1);
Thread two = new Thread(t2);
one.start();
two.start();
}
}end of class
因此,預期結果將是:一個98098,兩個98099,但事實證明結果是不可預測的,有時是78000或81000,我不知道。
但是,如果我添加一些代碼以打印當前計數值的一行,則最終結果將是正確的。
我真的不知道出了什么問題,甚至在ThreadOne和ThreadTwo的run()方法中添加了sync關鍵字,問題仍然存在。
我已經學習了3個月的Java,這是我所遇到的最難以捉摸的問題...所以在此先感謝任何人都可以幫助我了解多線程的基本知識...
代碼不同步。 由於未同步,因此嘗試更新計數器的其他Thread
可能同時出現,從而導致此問題。
如果您同步化updateCounter
,則將可以正確訪問此方法。
public synchronized void updateCounter(int add){
counter+=add;
}
在您的示例中, Accum
實例在線程之間共享。 您的更新過程是典型的READ,COMPUTE-UPDATE,WRITE操作序列。 因為資源是共享的而不是受保護的,所以這三個操作(來自兩個線程-進行六個操作)可以以許多不同的方式交錯,從而導致更新丟失。
這是操作順序的示例(數字表示線程):
READ #1 -> reads 10
COMPUTE-UPDATE #1 -> computes 1010
READ #2 -> reads 10
WRITE #1 -> writes 1010
COMPUTE-UPDATE #2 -> computes 11
WRITE #2 -> writes 11 (earlier update is lost)
如此看來,幾乎任何結果都是可能的。 如@SubhrajyotiMajumder所述,您可以使用synchronized
修復它。 但是,如果這樣做,線程可能不適合您的問題。 或者,您需要另一個算法過程。
您的代碼未正確同步。 作為同步方法的替代方法,我建議使用AtomicInteger
存儲從不同線程訪問和修改的變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.