在编写多线程应用程序时,遇到的最常见的问题之一是竞争条件。

我对社区的问题是:

竞态条件是什么? 你如何发现它们? 你是如何处理的? 最后,你如何防止它们的发生?


当前回答

如果你使用“原子”类,你可以防止竞争条件。原因是线程没有分开操作get和set,示例如下:

AtomicInteger ai = new AtomicInteger(2);
ai.getAndAdd(5);

因此,你将有7在链接“ai”。 虽然你做了两个操作,但这两个操作都确认了同一个线程,没有其他线程会干涉这,这意味着没有竞争条件!

其他回答

Race conditions occur in multi-threaded applications or multi-process systems. A race condition, at its most basic, is anything that makes the assumption that two things not in the same thread or process will happen in a particular order, without taking steps to ensure that they do. This happens commonly when two threads are passing messages by setting and checking member variables of a class both can access. There's almost always a race condition when one thread calls sleep to give another thread time to finish a task (unless that sleep is in a loop, with some checking mechanism).

防止竞争条件的工具依赖于语言和操作系统,但一些常见的工具是互斥锁、临界区和信号。互斥锁在你想确保你是唯一一个在做某事的时候很有用。当你想确保别人已经完成某件事时,信号是很好的。最小化共享资源还有助于防止意外行为

Detecting race conditions can be difficult, but there are a couple signs. Code which relies heavily on sleeps is prone to race conditions, so first check for calls to sleep in the affected code. Adding particularly long sleeps can also be used for debugging to try and force a particular order of events. This can be useful for reproducing the behavior, seeing if you can make it disappear by changing the timing of things, and for testing solutions put in place. The sleeps should be removed after debugging.

但是,如果某个问题只在某些机器上断断续续地发生,则是存在竞争条件的标志性标志。常见的错误是崩溃和死锁。使用日志记录,您应该能够找到受影响的区域并从那里返回。

什么是竞态条件?

You are planning to go to a movie at 5 pm. You inquire about the availability of the tickets at 4 pm. The representative says that they are available. You relax and reach the ticket window 5 minutes before the show. I'm sure you can guess what happens: it's a full house. The problem here was in the duration between the check and the action. You inquired at 4 and acted at 5. In the meantime, someone else grabbed the tickets. That's a race condition - specifically a "check-then-act" scenario of race conditions.

你如何发现它们?

宗教代码审查多线程单元测试没有捷径。在此基础上出现了一些Eclipse插件,但还没有稳定的插件。

你如何处理和预防它们?

最好的方法是创建无副作用和无状态的函数,尽可能使用不可变函数。但这并不总是可能的。使用java。util。concurrent。原子的、并发的数据结构、适当的同步和基于参与者的并发将有所帮助。

并发性的最佳资源是JCIP。你也可以在这里得到更多关于上述解释的细节。

什么是竞态条件?

过程严重依赖于其他事件的顺序或时间的情况。

例如, 处理器A和处理器B的执行都需要相同的资源。

你如何发现它们?

有一些工具可以自动检测竞态状态:

基于锁集的竞赛检查器 发生在种族检测之前 杂交种族检测

你是如何处理的?

竞争条件可以由互斥量或信号量处理。它们就像锁一样,允许进程根据特定的需求获取资源,以防止竞争。

你如何防止它们的发生?

防止竞争状态的方法有很多种,比如避免临界区。

没有两个进程同时在它们的关键区域内。(互斥) 没有对速度或cpu数量做任何假设。 没有进程运行在阻塞其他进程的关键区域之外。 没有进程需要永远等待才能进入临界区。(A等待B资源,B等待C资源,C等待A资源)

如果你使用“原子”类,你可以防止竞争条件。原因是线程没有分开操作get和set,示例如下:

AtomicInteger ai = new AtomicInteger(2);
ai.getAndAdd(5);

因此,你将有7在链接“ai”。 虽然你做了两个操作,但这两个操作都确认了同一个线程,没有其他线程会干涉这,这意味着没有竞争条件!

您并不总是希望丢弃竞态条件。如果你有一个可以被多个线程读写的标志,并且这个标志被一个线程设置为“done”,这样当标志被设置为“done”时,其他线程就会停止处理,你不希望这个“竞争条件”被消除。事实上,这可以被称为良性竞态条件。

然而,使用检测竞态条件的工具,它将被视为有害的竞态条件。

更多关于比赛情况的详细信息,请访问http://msdn.microsoft.com/en-us/magazine/cc546569.aspx。