开发者

Can this Java program ever print a value other than zero?

I have a favorite C# program similar to the one below that shows that if two threads share the same memory address for counting (one thread incrementing n times, one thread decrementing n times) you can get a final result other than zero. As long as n is reasonably large, it's pretty easy to get C# to display some non-zero value between [-n, n]. However, I can't get Java to produce a non-zero result even when increasing the number of threads to 1000 (500 up, 500 down). Is there some memory model or specification difference wrt C# I'm not aware of that guarantees this program will always yield 0 despite the scheduling or number of cores that I am not aware of? Would we agree that this program could produce a non-zero value even if we can not prove that experimentally?

(Not:, I found this exact question over here, but when I run that topic's code I also get zero.)

public class Counter
{
  private int _counter = 0;

  Counter() throws Exception
  {
    final int limit = Integer.MAX_VALUE;

    Thread add = new Thread()
    {
      public void run()
      {
        for(int i = 0; i<limit; i++)
        {
          _counter++;
        }
      }
    };

    Thread sub = new Thread()
    {
      public voi开发者_Python百科d run()
      {
        for(int i = 0; i<limit; i++)
        {
         _counter--;
        }
      }
    };

    add.run();
    sub.run();
    add.join();
    sub.join();

    System.out.println(_counter);
  }

  public static void main(String[] args) throws Exception
  {
    new Counter();
  }
}


The code you've given only runs on a single thread, so will always give a result of 0. If you actually start two threads, you can indeed get a non-zero result:

// Don't call run(), which is a synchronous call, which doesn't start any threads
// Call start(), which starts a new thread and calls run() *in that thread*.
add.start();
sub.start();

On my box in a test run that gave -2146200243.


Assuming you really meant start, not run.

On most common platforms it will very likely produce non zero, because ++/-- are not atomic operations in case of multiple cores. On single core/single CPU you will most likely get 0 because ++/-- are atomic if compiled to one instruction (add/inc) but that part depends on JVM.

Check result here: http://ideone.com/IzTT2


The problem with your program is that you are not creating an OS thread, so your program is essentially single threaded. In Java you must call Thread.start() to create a new OS thread, not Thread.run(). This has to do with a regrettable mistake made in the initial Java API. That mistake is that the designer made Thread implement Runnable.

add.start();
sub.start();
add.join();
sub.join();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜