9

我想知道有什么好的方法可以断言同步或其他东西,以便我可以检测同步违规(在测试时)。

例如,这将用于我有一个不是线程安全的类并且不会是线程安全的类的情况。以某种方式,如果从多个线程调用它的某些方法,我会有一些断言会通知我(日志或其他东西)。

我渴望可以为 AWT 调度线程制作类似的东西,如下所示:

public static void checkDispatchThread() {
    if(!SwingUtilities.isEventDispatchThread()) {
        throw new RuntimeException("GUI change made outside AWT dispatch thread");
    }
}

我只想要更一般的东西。问题描述不是很清楚,但我希望有人有一些好的方法=)

4

9 回答 9

2

你在寻找圣杯,我想。AFAIK 它不存在,Java 不是一种允许轻松创建这种方法的语言。

“Java Concurrency in Practice”有一节是关于测试线程问题的。它特别注意做起来有多难。

于 2008-11-18T14:37:40.173 回答
2

当 Java 中的线程出现问题时,它通常与死锁检测有关,而不仅仅是监视哪些线程同时访问同步部分。从 1.5 开始添加到 JRE 的JMX扩展可以帮助您检测这些死锁。事实上,我们在我们自己的软件中使用 JMX 来自动检测死锁并跟踪发现死锁的位置。

这是有关如何使用它的示例。

于 2008-11-18T14:41:24.910 回答
2

IntelliJ IDEA有很多有用的并发检查。例如,当您从同步和非同步上下文访问同一个对象时,当您在非最终对象上同步时,它会向您发出警告等等。

同样,FindBugs也有许多类似的检查

于 2008-11-18T19:27:29.403 回答
1

除了@Fernando 提到的线程死锁之外,多线程的另一个问题是并发修改及其可能导致的问题。

Java 在内部做的一件事是集合类记录它被更新的次数。然后迭代器检查每个 .next() 上的值与创建交互器时的值,以查看在迭代时集合是否已更新。我认为这个原则可以更普遍地使用。

于 2008-11-18T14:56:49.637 回答
1

试试ConTestCovertity

这两个工具都会分析代码以确定哪些部分数据可能在线程之间共享,然后它们检测代码(向已编译的类添加额外的字节码)以检查当两个线程尝试同时更改某些数据时它是否中断. 然后这两个线程一遍又一遍地运行,每次都以稍微不同的时间偏移量启动它们,以获得许多可能的访问模式组合。

另外,检查这个问题:单元测试多线程应用程序?

于 2008-11-18T15:13:40.337 回答
1

您可能对 Peter Veentjer 在博客中提到的一种方法感兴趣,他称之为并发检测器。我不相信他已经开源了这个,但正如他所描述的那样,基本思想是使用 AOP 来检测您对分析感兴趣的代码,并记录哪个线程已经触及了哪个字段。之后是手动或自动解析生成的日志的问题。

于 2008-11-18T15:59:24.173 回答
1

如果您可以识别线程不安全的类,静态分析可能会告诉您它们是否曾经“逃逸”以对多个线程可见。通常情况下,程序员会在头脑中这样做,但显然他们在这方面容易出错。一个工具应该能够使用类似的方法。

也就是说,从您描述的用例来看,这听起来像记住一个线程并对其进行断言这样简单的事情可能足以满足您的需求。

class Foo {

  private final Thread owner = Thread.currentThread();

  void x() {
    assert Thread.currentThread() == owner;
    /* Implement method. */
  }

}

即使断言被禁用,所有者引用仍然被填充,因此它不是完全“免费”的。我也不想用这个样板把我的许多课程弄得乱七八糟。

Thread.holdsLock (Object)方法也可能对您有用。

于 2008-11-18T16:00:42.253 回答
0

对于您给出的具体示例,SwingLabs 有一些帮助代码来检测事件线程违规和挂起。 https://swinghelper.dev.java.net/

不久前,我使用了 JProbe java 分析工具。他们的工具之一(threadalyzer?)寻找线程同步违规。查看他们的网页,我没有看到同名的工具或我记得的工具。但你可能想看看。 http://www.quest.com/jprobe/performance-home.aspx

于 2008-11-18T14:33:54.207 回答
-1

您可以使用Netbeans 分析器JConsole深入检查线程状态

于 2008-11-18T15:44:43.533 回答