主线程在无限循环中停止

时间:2014-04-10 13:35:51

标签: java multithreading loops user-interface

我有一个小程序向用户显示选择文件的GUI,程序然后根据文件内容执行并相应地显示结果。

这是在主线程中运行的循环(main()方法):

do {
    args = fg.getFile();
} while (!fg.started);

fg.started是一个布尔变量,当用户选择了一个文件并按下“开始”按钮时,该变量设置为true。

然而,这不起作用除非我在循环中放置一个随机任务:

do {
    args = fg.getFile();
    System.out.println("");
} while (!fg.started);

这很有效。

任何人都可以向我解释为什么会这样吗?

我知道有一个涉及Thread类的解决方案,notify()wait()等,但现在我只是对此感到好奇。

2 个答案:

答案 0 :(得分:2)

您应该同步fg的访问权限,否则可能会发生这种情况:

  • Thread1可能会变为活动状态,访问并因此阻止fg,然后暂停。
  • Thread2变为活动状态,无法访问fg并立即停用。
  • Thread1再次处于活动状态,可以即时重新访问 fg完成任务,然后暂停。
  • Thread2 becomse active and ...该死的! fg再次被锁定!

如果您需要有关并发/并行执行的帮助/说明,请参阅Oracle - Syncronization以获取信息。

答案 1 :(得分:2)

  

fg.started是一个布尔变量,当用户选择了一个文件并按下“开始”按钮时,该变量设置为true。

     

然而,这不起作用除非我在循环中放置一个随机任务:

这是因为两个线程正在访问started字段而没有内存同步。您没有显示fg.started的定义,但我怀疑您需要确保它是volatile。您也可以考虑切换到AtomicBoolean。这是Java tutorial about memory synchronization

volatile boolean started;

多线程应用程序的问题是程序的某些部分可以在具有自己的本地内存缓存的不同处理器中运行。每当线程修改或访问共享字段时,都需要进行显式同步,以确保它们不仅仅是查看字段的本地缓存值。

添加System.out.println(...)时它正在工作,因为PrintStream的方法已同步,因此您要添加间接内存同步。

  

使getFile()同步修复它,谢谢。小心解释原因? :)

因为,与System.out.println(...)一样,您正在添加间接同步。