2016-01-22 85 views
0

我只需要用java線程做一個競爭條件的例子,我編寫了這段代碼,但我不確定它是否有競爭條件。這段代碼是否有競爭狀態?

有人可以告訴我,如果下面的代碼有競爭條件,以及我怎樣才能改善或簡化?

(抱歉不好英語)

public class RaceCondition extends Thread{ 

static int count=0; //the variable where the race condition need to happen 
static int contador1 = 0; //variables to count 
static int contador2 = 0; 


static Thread t1 = new Thread(new Runnable() { 
    public void run(){ 

     while(contador1!=20){ 
     count ++; 
     System.out.print(count + " "); 
     contador1++; 

     } 
    } 
    }); 

static Thread t2 = new Thread(new Runnable() { 
    public void run(){ 
     while(contador2!=20){ 

     int k = 5; 
     count += 5*k; 
     System.out.print(count + " "); 
     contador2 ++; 

     } 
    } 
    }); 

public static void main(String[] args) { 

    t1.start(); 
    System.out.println(" "); 
    t2.start(); 

    } 

} 
+5

代碼必須運行纔能有競爭狀態。我沒有看到「count」的聲明。這段代碼是否編譯? – erickson

+1

@user如果程序運行,線程將繼續運行直到它們完成,因爲它們不是守護進程線程。你在看什麼? – erickson

+0

@user主線程在主線程完成後將死亡,線程不會。 –

回答

0

您沒有任何競爭狀態。線程只能分別訪問變量contador1contador2。兩個線程都沒有修改或讀取的變量。

t2甚至有它自己使用的本地k,而不是您標記的k

count在哪裏申報?

+0

對不起,k實際上是計數變量。 –

0

爲了有競爭條件,您需要有讀/寫共享內存部分的線程(例如全局/靜態變量)。在這裏,你的線程不會相互作用,因此沒有競爭條件。此外,您在線索2代碼內部重新購買k,因此您的全球k從不使用。

試試這個:當兩個或多個線程可以訪問共享數據

public class RaceCondition extends Thread{ 

    static int k = 0;  //the variable where the race condition need to happen 


    public void run(){ 

     while(k != 20){ 
      k++; 
      try{ 
       Thread.sleep(1); 
      }catch(InterruptedException e){ 

      } 
      System.out.print(k + " "); 

     } 
    } 


    public static void main(String[] args){ 

     RaceCondition t1 = new RaceCondition(); 
     RaceCondition t2 = new RaceCondition(); 
     t1.start(); 
     t2.start(); 
    } 

} 
0

「,發生競爭狀態,他們試圖在同一時間來改變它,因爲線程調度算法,可以在線程之間進行切換。任何時候,您都不知道線程嘗試訪問共享數據的順序,因此,數據更改的結果取決於線程調度算法,即兩個線程都「競相」訪問/更改數據。」 SOURCE = What is a race condition?

請注意這部分「數據更改的結果取決於線程調度算法」以及如何在代碼中操作變量計數。

0

否。當兩個或多個線程訪問導致結果問題的相同變量時,會發生競態條件。例如,

static int a = 2; 
static int b = 0; 

static Thread t1 = new Thread(new Runnable() { 
    public void run(){ 
     if(a == 2) { 
      b = 5 * a; 
      System.out.println(a); 
     } 
    } 
}); 

static Thread t2 = new Thread(new Runnable() { 
    public void run(){ 
     a = 5; 
    } 
}); 

這裏,只考慮後,線程1執行if(a == 2),線程2改變a = 5值。所以,而不是得到預期的價值10,我們會得到25

-1

這是代碼:

package RaceCondition; 

public class RaceCondition extends Thread { 

    static int count = 0; 
    static int contador1 = 0; 
    static int contador2 = 0; 

    static Thread t1 = new Thread(new Runnable() { 
     public void run() { 

      while (contador1 != 20) { 
       count++; 
       System.out.print(count + " "); 
       contador1++; 
      } 
      System.out.println("fine t1"); 

     } 
    }); 

    static Thread t2 = new Thread(new Runnable() { 
     public void run() { 
      while (contador2 != 20) { 
       int k = 5; 

       count += 5; 

       System.out.print(count + " "); 
       contador2++; 
      } 
      System.out.println("fine t2"); 
     } 
    }); 

    public static void main(String[] args) { 

     t1.start(); 
     System.out.println(" "); 

     t2.start(); 

    } 

} 
5

你有一個競爭條件。 +++=操作都不作爲Java中的原子操作實現,當兩個線程都嘗試讀取和更新計數字段時,它們可能會相互干擾。

此外,不能保證對共享變量的更新將在跨線程可見,因此一個線程甚至不會看到其他線程的更新值。

您可以通過使計數靜態變量爲AtomicInteger來解決這兩個問題。使用getAndIncrement而不是++getAndAdd而不是+=

爲什麼++的工作原理請參考Why ++ is not implemented as an atomic operation in Java

+1

最後。正確答案在不正確的部分。 – SergeyA

+0

@SergeyA:謝謝:-)它幫助OP糾正了他的代碼,其他答案都是基於舊版本的。 –