【问题标题】:What is the output of the following program? Can anyone explain how the program executes?以下程序的输出是什么?谁能解释一下程序是如何执行的?
【发布时间】:2015-08-13 09:32:36
【问题描述】:
class A implements Runnable{
   int i=0;
   public void run(){
      System.out.println("Thread-"+i++);
   }
}

class Demo {
   public static void main(String []args) {
      A a=new A();
      Thread t1=new Thread(a);
      Thread t2=new Thread(a);
      Thread t3=new Thread(a);
      t1.start();
      t2.start();
      t3.start();
   }
}

谁能解释一下这段代码是如何执行的以及输出是什么?

【问题讨论】:

  • 为什么不直接运行一下试试?
  • @Simz 实验并不一定会导致理解。我认为这将是一个很好的主题问题,它会不会是同类的第 1000 个化身,使其明显重复。

标签: java multithreading concurrency


【解决方案1】:

输出将是

Thread-0
Thread-1
Thread-2

顺序保持不变,因为它们已同步。在线查看结果 - IDEone。

【讨论】:

  • 这是一个特例。有一组可能的结果,这只是其中之一。 i++ 可以同时执行并且会产生几个可能的输出。尽管我们知道 i 在执行结束时可以有什么值,但我们称之为 non-deterministic algorithm。
【解决方案2】:

您希望输出是:

Thread-0  
Thread-1  
Thread-2

但是,如果您拥有一台多核机器,您会在运行几次后发现它并不总是会打印此结果。

如果您想知道为什么输出与您预期的不同,那是因为线程是同时运行的(同时)。 由于没有什么可以阻止线程同时递增i,因此两个或多个线程可以同时执行完全相同的操作(例如,将i 从0 递增到1)。

我必须运行几次才能获得并发访问并得到以下结果:

Thread-0
Thread-0
Thread-1

像这样可以产生多种不同结果的程序称为nondeterministic。这是存在data race(访问i 变量)的特殊情况。

修复此行为并获得一致输出的几种方法是使用锁定对象使i++ 操作原子,或使用AtomicInteger 而不是int。

【讨论】:

  • 有人可以向我解释为什么我投了反对票吗?我写错了吗?
  • (我不是投反对票的人,但我猜)投反对票的一个很好的理由是半句But if you own a multi-threaded machine,好像提问者在现实生活中可能会使用一些袖珍计算器自定义单线程操作系统。 (我猜你的意思是一台多核机器。)
  • @mg30rg 我会编辑的,谢谢。无论如何,机会对我来说似乎很真实,以 Arulx Z 的回答为例,他甚至说顺序保持不变。
  • 编辑后我认为您的答案没有问题(如果它有术语 "undeterministic",我什至会赞成它)。另外,如果Arulx Z's answer 还没有达到 0pt,我会否决。
  • @mg30rg 非常感谢您的反馈。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-18
  • 1970-01-01
  • 2015-11-01
  • 2017-03-25
  • 2022-01-03
相关资源
最近更新 更多