简体   繁体   English

哪一个更好的性能来检查java中的另一个线程boolean

[英]Which one is better for performance to check another threads boolean in java

while(!anotherThread.isDone());

or 要么

while(!anotherThread.isDone())
    Thread.sleep(5);

If you really need to wait for a thread to complete, use 如果您确实需要等待线程完成,请使用

anotherThread.join()

(You may want to consider specifying a timeout in the join call.) (您可能需要考虑在连接调用中指定超时。)

You definitely shouldn't tight-loop like your first snippet does... and sleeping for 5ms is barely better. 肯定不应该像你的第一个片段那样紧密循环...而且睡眠5ms几乎没有好转。

If you can't use join (eg you're waiting for a task to complete rather than a whole thread) you should look at the java.util.concurrent package - chances are there's something which will meet your needs. 如果您不能使用join (例如,您正在等待任务完成而不是整个线程),那么您应该查看java.util.concurrent包 - 有可能满足您的需求。

IMHO, avoid using such logic altogether. 恕我直言,完全避免使用这种逻辑。 Instead, perhaps implement some sort of notification system using property change listeners. 相反,也许使用属性更改侦听器实现某种通知系统。

I would recommend utilizing the wait/notify mechanism that is built into all Java objects (or using the new Lock code in Java 5 ). 我建议使用内置于所有Java对象中的wait / notify机制(或使用Java 5中的新Lock代码 )。

Thread 1 (waiting for Thread2) 线程1(等待Thread2)

while(!thread2.isDone()) {
  synchronize(thread2.lockObject) {
    thread2.lockObject.wait();
  }
}

Thread 2 线程2

// finish work, set isDone=true, notify T1
thread2.lockObject.notify();

'lockObject' is just a plain (Object lockObject = new Object()) -- all Java objects support the wait/notify calls. 'lockObject'只是一个普通的(Object lockObject = new Object()) - 所有Java对象都支持wait / notify调用。

After that last call to notify(), Thread1 will wake up, hit the top of the while, see that T2 is now done, and continue execution. 在最后一次调用notify()之后,Thread1将被唤醒,点击顶部,看到T2现在已经完成,并继续执行。

You should account for interrupt exceptions and the like, but using wait/notify is hugely helpful for scenarios like this. 您应考虑中断异常等,但使用wait / notify对此类情况非常有用。

If you use your existing code, with or without sleep, you are burning a huge number of cycles doing nothing ... and that's never good. 如果你使用你现有的代码,无论是否有睡眠,你都会在无所事事的情况下燃烧大量的循环......而且这种情况永远都不会好。

ADDENDUM 附录

I see a lot of comments saying to use join - if the executing thread you are waiting on will complete, then yes, use join. 我看到很多评论说要使用join - 如果你正在等待的执行线程将完成,那么是的,使用join。 If you have two parallel threads that run at all times (eg a producer thread and a consumer) and they don't "complete", they just run in lock-step with each other, then you can use the wait/notify paradigm I provided above. 如果你有两个并行运行的线程(例如一个生产者线程和一个消费者)并且它们没有“完成”,它们只是彼此锁定一步,那么你可以使用wait / notify范例我以上提供。

As others have said, it's better to just use join in this case. 正如其他人所说,在这种情况下最好只使用join However, I'd like to generalize your question and ask the following: 但是,我想概括一下你的问题并提出以下问题:

In general when a thread is waiting for an event that depends on another thread to occur is it better to: 通常,当一个线程正在等待依赖于另一个线程发生的事件时,最好是:

  1. Use a blocking mechanism (ie join, conditional variable, etc.) or 使用阻塞机制(即连接,条件变量等)或
  2. Busy spin without sleep or 忙着旋转没有睡觉或
  3. Busy spin with sleep? 忙着旋转睡觉?

Now let's see what are the implications for each case: 现在让我们看看每种情况的含义是什么:

  1. In this case, using a blocking call will effectively take your thread off the CPU and not schedule it again until the expected event occurs. 在这种情况下,使用阻塞调用将有效地使您的线程脱离CPU,并且不会再次安排它直到预期的事件发生。 Good for resource utilization (the thread would waste CPU cycles otherwise), but not very efficient if the event may occur very frequently and at small intervals (ie a context switch is much more time-consuming than the time it takes for the event to occur). 有利于资源利用(否则线程会浪费CPU周期),但如果事件可能非常频繁地以较小的间隔发生,则效率不高(即上下文切换比事件发生所花费的时间更耗时) )。 Generally good when the event will occur eventually, but you don't know how soon. 一般情况下最终会发生好事,但你不知道多久。
  2. In case two, you are busy spinning, meaning that you are actively using the CPU without performing useful work. 在第二种情况下,您正忙着旋转,这意味着您正在积极使用CPU而不执行有用的工作。 This is the opposite of case 1: it is useful when the event is expected to occur very very soon , but otherwise may occupy the CPU unnecessarily. 这与情况1相反:当预期事件很快发生时,它很有用,但否则可能会不必要地占用CPU。
  3. This case is a sort of trade-off. 这种情况是一种权衡。 You are busy spinning, but at the same time allowing other threads to run by giving up the CPU. 您正忙着旋转,但同时允许其他线程通过放弃CPU来运行。 This is generally employed when you don't want to saturate the CPU, but the event is expected to occur soon and you want to be sure that you will still be there in almost real time to catch it when it occurs. 当你不想让CPU饱和时,通常会使用这种方法,但是事件很快就会发生,并且你想确保在它发生时几乎可以实时捕获它。

The second one. 第二个。

Better though is to use the join() method of a thread to block the current thread until it is complete :). 但更好的方法是使用线程的join()方法阻塞当前线程,直到它完成:)。

EDIT: 编辑:

I just realised that this only addresses the question as it applies to the two examples you gave, not the question in general (how to wait for a boolean value to be changed by another Thread, not necessarily for the other Thread to actually finish). 我刚刚意识到这只能解决这个问题,因为它适用于你给出的两个例子,而不是一般的问题(如何等待另一个线程改变一个布尔值,不一定是另一个线程实际完成)。

To answer the question in general I would suggest that rather than using the methods you described, to do something like this I would recommend using the guarding block pattern as described here . 为了回答这个问题,我建议不要使用你描述的方法来做这样的事情,我建议使用这里描述的防护块模式。 This way, the waiting thread doesn't have to keep checking the condition itself and can just wait to be notified of the change. 这样,等待线程不必继续检查条件本身,只需等待通知更改。 Hope this helps! 希望这可以帮助!

Have you considered: anotherThread.join() ? 你有没有考虑过: anotherThread.join() That will cause the current one to be 'parked' without any overhead until the other one terminates. 这将导致当前的一个被“停放”而没有任何开销,直到另一个终止。

The second is better than the first, but neither is very good. 第二个比第一个好,但两个都不是很好。 You should use anotherThread.join() (or anotherThread.join(timeout) ). 您应该使用anotherThread.join() (或anotherThread.join(timeout) )。

Neither, use join() instead: 也不要使用join()代替:

anotherThread.join();
// anotherThread has finished executing.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM