-1

我正在测试一个多线程 Java 程序。为了调试,我让线程打印出语句。打印输出的顺序如下:

  • 主题消息 1
  • 主题消息 2
  • 主题消息 1
  • 主题消息 2

问题是在某台机器上它变为:

  • 主题消息 1
  • 主题消息 1
  • 主题消息 2
  • 主题消息 2

该机器与我测试的所有其他机器具有相同版本的 Java。起初我以为是 Windows 8 的问题,因为以前的都是 Windows 7,但我在另一台 Windows 8 机器上试了一下,它工作正常。所以我的问题是还有哪些其他变量会影响 Java 中的线程调度?仅供参考,发生错误顺序的机器是带有 Windows 8 的 Acer Aspire E1-521-0694 AMD Dual Core E2-1800。

4

5 回答 5

7

机器发生错误的顺序

在处理非同步多线程时,没有“不正确”的顺序。事情将按照它们发生的顺序发生,期间。如果您需要强制事情以特定顺序发生,则需要添加同步(Oracle 教程请参见:http ://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html )。

出于所有意图和目的,线程调度是完全不可预测的,否则会让您陷入困境。

于 2013-06-28T21:16:56.100 回答
2

假设 Java 使用操作系统的线程实现,没有定义线程应该运行的顺序。这正是诸如http://en.wikipedia.org/wiki/Race_condition之类的东西存在的原因。

事实上,如果您在完全相同的机器上运行该程序 100 次,并且每次更改顺序,我一点也不感到惊讶。如果您需要确保某些事情先于其他事情发生,那么您需要将同步添加到您的线程 ( http://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html )。

还可能值得注意的是,无论您使用的是 Java,还是使用 C 中的 pthreads 或其他任何东西,都或多或少是相同的事情。如果没有某种同步代码来强制它以特定方式发生,线程调度通常是未定义的。

于 2013-06-28T21:20:06.840 回答
1

通过线程,JVM 只提供并行性。没有任何订单的保证。这完全取决于线程调度程序(通过它使用的时间片算法)来决定哪个线程应该运行以及哪个应该等待。

忘记比较两台不同机器上的序列。相同的 JVM 环境可以在多次运行中以完全不同的顺序运行您的程序。程序依赖线程排序来保证其正确性是完全不正确的。

为了带来任何秩序,线程必须通过同步(使用锁)相互通信,有时共享一个数据对象(兼作锁)以等待()通知()

为线程设置优先级是影响调度程序的另一种方式。但是,在这里,不同的 JVM 也会给你不同的结果。施加的影响程度会有所不同。

于 2013-06-28T21:25:07.087 回答
1

google上有很多关于这个的帖子和主题,所以我只是将它们总结一下。

您可以尝试尽可能多地安排线程并确定其优先级,但最终 JVM 可以随心所欲地做任何事情。所以你真的不能保证什么。

于 2013-06-28T21:17:54.550 回答
0

Sun/Oracle 的 HotSpot JVM 将 Java 线程映射到操作系统线程,然后由您的操作系统调度它们。优先级可以产生影响,即Thread.setPriority但不提供任何保证。

正如其他人所说 - 您需要使用同步机制来强制排序。

于 2013-06-28T23:26:30.970 回答