如何使用 Java 检测同步冲突

发布于 2024-07-09 05:38:36 字数 448 浏览 10 评论 0原文

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

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

我渴望为 AWT 调度线程制作类似的东西,具有以下内容:

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

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

I'm wondering what good ways there would be make assertions about synchronization or something so that I could detect synchronization violations (while testing).

That would be used for example for the case that I'd have a class that is not thread-safe and that isn't going to be thread-safe. With some way I would have some assertion that would inform me (log or something) if some method(s) of it was called from multiple threads.

I'm longing for something similar that could be made for AWT dispatch thread with the following:

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

I'd only want something more general. The problem description isn't so clear but I hope somebody has some good approaches =)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

悲喜皆因你 2024-07-16 05:38:36

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

《Java 并发实践》中有一节是关于测试线程问题的。 它特别引起人们注意它的难度。

You are looking for the holy grail, I think. AFAIK it doesn't exist, and Java is not a language that allows such an approach to be easily created.

"Java Concurrency in Practice" has a section on testing for threading problems. It draws special attention to how hard it is to do.

决绝 2024-07-16 05:38:36

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

这是一个关于如何使用它的示例

When an issue arises over threads in Java it is usually related to deadlock detection, more than just monitoring what Threads are accessing a synchronized section at the same time. JMX extension, added to JRE since 1.5, can help you detect those deadlocks. In fact we use JMX inside our own software to automatically detect deadlocks an trace where it was found.

Here is an example about how to use it.

满地尘埃落定 2024-07-16 05:38:36

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

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

IntelliJ IDEA has a lot of useful concurrency inspections. For example, it warns you when you are accessing the same object from both synchronised and unsynchronised contexts, when you are synchronising on non-final objects and more.

Likewise, FindBugs has many similar checks.

一曲爱恨情仇 2024-07-16 05:38:36

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

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

As well as @Fernando's mention of thread deadlocking, another problem with multiple threads is concurrent modifications and the problems it can cause.

One thing that Java does internally is that a collection class keeps a count of how many times it's been updated. And then an iterator checks that value on every .next() against what it was when the interator was created to see if the collection has been updated while you were iterating. I think that principle could be used more generally.

花辞树 2024-07-16 05:38:36

尝试 ConTestCoverity

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

另外,请检查以下问题:对多线程应用程序进行单元测试?

Try ConTest or Covertity

Both tools analyze the code to figure out which parts of the data might be shared between threads and then they instrument the code (add extra bytecode to the compiled classes) to check if it breaks when two threads try to change some data at the same time. The two threads are then run over and over again, each time starting them with a slightly different time offset to get many possible combinations of access patterns.

Also, check this question: Unit testing a multithreaded application?

别忘他 2024-07-16 05:38:36

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

You might be interested in an approach Peter Veentjer blogged about, which he calls The Concurrency Detector. I don't believe he has open-sourced this yet, but as he describes it the basic idea is to use AOP to instrument code that you're interested in profiling, and record which thread has touched which field. After that it's a matter of manually or automatically parsing the generated logs.

孤蝉 2024-07-16 05:38:36

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

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

class Foo {

  private final Thread owner = Thread.currentThread();

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

}

即使断言被禁用,所有者引用仍然会被填充,因此它并不完全“免费”。 我也不想用这个样板来扰乱我的许多课程。

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

If you can identify thread unsafe classes, static analysis might be able to tell you whether they ever "escape" to become visible to multiple threads. Normally, programmers do this in their heads, but obviously they are prone to mistakes in this regard. A tool should be able to use a similar approach.

That said, from the use case you describe, it sounds like something as simple as remembering a thread and doing assertions on it might suffice for your needs.

class Foo {

  private final Thread owner = Thread.currentThread();

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

}

The owner reference is still populated even when assertions are disabled, so it's not entirely "free". I also wouldn't want to clutter many of my classes with this boilerplate.

The Thread.holdsLock(Object) method may also be useful to you.

疯了 2024-07-16 05:38:36

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

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

For the specific example you give, SwingLabs has some helper code to detect event thread violations and hangs. https://swinghelper.dev.java.net/

A while back, I worked with the JProbe java profiling tools. One of their tools (threadalyzer?) looked for thread sync violations. Looking at their web page, I don't see a tool by that name or quite what I remember. But you might want to take a look. http://www.quest.com/jprobe/performance-home.aspx

凶凌 2024-07-16 05:38:36

您可以使用 Netbeans profilerJConsole 深入检查线程状态

You can use Netbeans profiler or JConsole to check the threads status in depth

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文