在Java中使用轮询不好吗?

2022-09-01 09:28:10

我有几个作为数据队列工作。每个队列都链接到一个单独的线程,该线程检查其中是否有一些数据。ArrayListsArrayList

 while (array.size == 0) {
    // nothing
 }

 // do stuff with one element of the array
 // remove element from array
 // and call the loop again

我在嵌入式系统编程中也做过类似的事情,但是在Java中使用它是否安全?问题在于通过迭代来浪费过程功率,同时循环得非常快。

可以通过每100ms添加和检查一次来解决,但话又说回来 - 响应时间较慢。Thread.sleep(100)

问题是 - 我需要添加睡眠还是不应该担心这一点?

对更安全/更好的系统检查数组中的新数据有什么建议吗?


答案 1

ArrayList 不是线程安全集合,因此,如果一个线程向列表中添加数据,而另一个线程尝试从同一列表中检索数据,则无法保证另一个线程会看到添加的元素。

像您描述的那样忙于等待会不必要地消耗CPU资源。

既然你似乎需要一个队列,你为什么不使用一个队列,比如ArrayBlockingQueue。它有一个 take 方法,该方法将在不消耗 CPU 周期的情况下阻塞,直到将项目添加到队列中。而且它是线程安全的。


答案 2

除非你需要等待的时间非常非常短,因此使上下文切换过于昂贵,否则我不会使用旋转。它肯定会无缘无故地浪费CPU周期。

您应该使用或其他一些信令机制来挂起线程,并仅在必要时将其唤醒。wait/notify

转到更高级的构造,有用于生产者 - 消费者模式的专用数据结构,例如BlocklingQueue(选择一个实现):

一个队列,它另外支持在检索元素时等待队列变为非空,并在存储元素时等待队列中空间变为可用的操作。