Java 产生一致结果的非同步方法

Java 产生一致结果的非同步方法,java,concurrency,Java,Concurrency,我是Java新手,喜欢玩线程。我编写这个小程序是为了检查当3个线程访问一个不同步的方法时会发生什么: class SharedValueHolder { public static int globalCounter = 0; public static void increment() { globalCounter++; } } class Incrementor implements Runnable { public void run() { for (

我是Java新手,喜欢玩线程。我编写这个小程序是为了检查当3个线程访问一个不同步的方法时会发生什么:

class SharedValueHolder {
  public static int globalCounter = 0;
  public static void increment() {
    globalCounter++;
  }
}

class Incrementor implements Runnable {
  public void run() {
    for (int i = 0; i < 5; i++) {
      //reportValue();
      SharedValueHolder.increment();
    }
  }

  private void reportValue() {
    String threadName = Thread.currentThread().getName();
    System.out.println(threadName + " - " + SharedValueHolder.globalCounter);
  }
}

public class ThreadTest {
  public static void main(String... args) throws InterruptedException {
    runTest();
  }

  private static void runTest() throws InterruptedException {
    Thread thread1 = new Thread(new Incrementor());
    Thread thread2 = new Thread(new Incrementor());
    Thread thread3 = new Thread(new Incrementor());

    thread1.start();
    thread2.start();
    thread3.start();

    Thread.sleep(300);
    System.out.println(SharedValueHolder.globalCounter);
  }
}

这清楚地表明线程在相同的时间“看到”相同的值,但结果仍然是正确的。有人能给我解释一下这是如何工作的吗?

并发性不是一个容易的话题,它很棘手的原因之一是,有时您可能会得到正确的结果(并且认为您的代码很好),但这并不意味着代码真的是正确的;这意味着给定运行它的环境,线程的数量。。。它工作得很好。但在高度并发的环境中,它可能会失败

尽管如此,你说你几乎总是看到相同的结果,这使得它并不总是如此

这也是问题的范围,只有5个元素的循环。当第一个线程完成时,第二个和第三个线程可能还没有开始

但很容易看出这是错误的。请尝试运行此示例:

class SharedValueHolder {
  public static int counter = 0;
}

class Incrementor implements Runnable {
  public void run() {
    for (int i = 0; i < 100000; i++) {
      SharedValueHolder.counter++;
    }
  }
}

public class ThreadTest {
  public static void main(String... args) throws InterruptedException {
    Thread thread1 = new Thread(new Incrementor());
    Thread thread2 = new Thread(new Incrementor());
    thread1.start();
    thread2.start();

    Thread.sleep(2000);
    System.out.println(SharedValueHolder.counter);
  }
}

“我确实得到了14分,但这是非常罕见的。”-所以这并不一致。。。正如预期的那样。您是如何得出“线程”在同一时间看到“相同的值”的结论的?输出不能说明这一点,不是吗?正如我所说,我对Java是新手。什么是一个好的方法来验证这一点?事实上,在“10”之后有“1”看起来。。。可疑。我不确定你在问什么,是“为什么它不总是工作”还是“为什么它有时工作”?好吧,我收回一句,x++不是原子的:
class SharedValueHolder {
  public static int counter = 0;
}

class Incrementor implements Runnable {
  public void run() {
    for (int i = 0; i < 100000; i++) {
      SharedValueHolder.counter++;
    }
  }
}

public class ThreadTest {
  public static void main(String... args) throws InterruptedException {
    Thread thread1 = new Thread(new Incrementor());
    Thread thread2 = new Thread(new Incrementor());
    thread1.start();
    thread2.start();

    Thread.sleep(2000);
    System.out.println(SharedValueHolder.counter);
  }
}
102472
105560
121472
139343
120953