为什么这些线程会返回错误的计算?

时间:2014-10-26 21:14:59

标签: java multithreading concurrency distributed-computing

我对并发编程很新,到目前为止我很享受:)!但是我刚刚意识到并发编程是多么棘手。

我有多个线程执行自己的计算。每个线程对某个变量进行操作并返回结果,但返回的结果不正确。

此类执行线程计算:

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 {

public static void main(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!");
  }

}

这里的问题在哪里?

1 个答案:

答案 0 :(得分:1)

您的' testVariable'应标记为“易变”。有关详细信息,请参阅此主题:Volatile Vs Static in java