2014-10-26 62 views
0

我對併發編程還很陌生,到目前爲止我都很享受:)!但是我只是意識到併發編程是多麼棘手。爲什麼這些線程返回錯誤的計算?

我有多個線程執行他們自己的計算。每個線程對某個變量進行操作並返回結果,但返回的結果不正確。

該類執行線程計算:

public class SharedDataThread extends Thread { 

private SharedData mySharedData; 
private String myThreadName; 
private static long testVariable = 0; 

// Setup the thread 

SharedDataThread(String name, SharedData sharedstuff) { 
    super(name); 
    mySharedData = sharedstuff; 
    myThreadName = name; 
} 


public void run() { 

    System.out.println(myThreadName + " is running"); 
    Thread me = Thread.currentThread(); // get a ref to the current thread 

    if (me.getName() == "myThread1") { 
     try { 
      sleep(2000); 

      mySharedData.acquireLock(); 
      System.out.println(me.getName() 
        + " is performing computations!"); 

      testVariable = testVariable + 20; 
      testVariable = testVariable * 5; 
      testVariable = testVariable/3; 

      System.out.println(me.getName() + " modified the value to : " 
        + testVariable + "\n"); 

      sleep(2000); 
      mySharedData.releaseLock(); 
     } catch (InterruptedException e) { 
      System.err.println("Failed to get lock when reading:" + e); 
     } 
    } else if (me.getName() == "myThread2") { 
     try { 
      sleep(2000); 

      mySharedData.acquireLock(); 
      System.out.println(myThreadName 
        + " is performing computations!"); 

      testVariable = testVariable - 5; 
      testVariable = testVariable * 10; 
      testVariable = (long) (testVariable/2.5); 

      System.out.println(me.getName() + " modified the value to : " 
        + testVariable + "\n"); 

      sleep(2000); 
      mySharedData.releaseLock(); 
     } catch (InterruptedException e) { 
      System.err.println("Failed to get lock when reading:" + e); 
     } 
    } else if (me.getName() == "myThread3") { 
     try { 
      sleep(2000); 

      mySharedData.acquireLock(); 

      System.out.println(me.getName() 
        + " is performing computations!"); 

      testVariable = testVariable - 50; 
      testVariable = testVariable/2; 
      testVariable = testVariable * 33; 

      System.out.println(me.getName() + " modified the value to : " 
        + testVariable + "\n"); 

      sleep(2000); 
      mySharedData.releaseLock(); 
     } catch (InterruptedException e) { 
      System.err.println("Failed to get lock when reading:" + e); 
     } 
    } else { 
     try { 
      sleep(2000); 

      mySharedData.acquireLock(); 
      System.out.println(me.getName() 
        + " is performing computations!"); 

      testVariable = testVariable * 20; 
      testVariable = testVariable/10; 
      testVariable = testVariable - 1; 

      System.out.println(me.getName() + " modified the value to : " 
        + testVariable + "\n"); 

      sleep(2000); 

      mySharedData.releaseLock(); 
     } catch (InterruptedException e) { 
      System.err.println("Failed to get lock when reading:" + e); 
     } 
    } 
    System.out.println("The final result of the variable is " 
      + testVariable); 
} 

}

線程是在另一個類執行自己的主線程中執行:

public class SharingExample { 

公共靜態無效的主要( String [] args){

SharedData mySharedData = new SharedData(); 


SharedDataThread myThread1 = new SharedDataThread("myThread1", mySharedData); 
SharedDataThread myThread2 = new SharedDataThread("myThread2", mySharedData); 
SharedDataThread myThread3 = new SharedDataThread("myThread3", mySharedData); 
SharedDataThread myThread4 = new SharedDataThread("myThread4", mySharedData); 


// Now start the threads executing 

myThread1.start(); 
myThread2.start(); 
myThread3.start(); 
myThread4.start(); 

} }

SharedData類只是一個用於實現鎖等的類。

public class SharedData { 

    private boolean accessing=false; // true a thread has a lock, false otherwise 
    private int threadsWaiting=0; // number of waiting writers 

    // attempt to acquire a lock 
    public synchronized void acquireLock() throws InterruptedException{ 
    Thread me = Thread.currentThread(); // get a ref to the current thread 
    System.out.println(me.getName()+" is attempting to acquire a lock!"); 

    ++threadsWaiting; 
    while (accessing) { // while someone else is accessing or threadsWaiting > 0 
     System.out.println(me.getName()+" waiting to get a lock as someone else is accessing..."); 
     //wait for the lock to be released - see releaseLock() below 
    wait(); 
    } 
    // nobody has got a lock so get one 
    --threadsWaiting; 
    accessing = true; 
    System.out.println(me.getName()+" got a lock!"); 
    } 

    // Releases a lock to when a thread is finished 

    public synchronized void releaseLock() { 
     //release the lock and tell everyone 
     accessing = false; 
     notifyAll(); 
     Thread me = Thread.currentThread(); // get a ref to the current thread 
     System.out.println(me.getName()+" released a lock!"); 
    } 

} 

問題在哪裏?

+0

'testVariable'是否應該在所有線程中共享,或者每個線程應該使用自己的'testVariable'進行計算? – isklenar 2014-10-26 21:22:27

+0

顯示'SharedData',以便我們知道鎖是如何實現的。另外,什麼是錯誤的輸出,你期望它是什麼? – RealSkeptic 2014-10-26 21:24:19

+0

這是正確的,我做了testVariable靜態的目的,它可以在線程之間共享,並且每個執行該testVariable的計算。 – 2014-10-26 21:25:03

回答

1

你的'testVariable'應該被標記爲'volatile'。有關更多信息,請參閱此主題:Volatile Vs Static in java

+1

這是不正確的。 'acquireLock'''relaseLock'方法引發*發生前*邊緣。 – 2014-10-26 21:34:17

相關問題