【问题标题】:Java: Keep order using threadsJava:使用线程保持秩序
【发布时间】:2015-07-28 16:52:31
【问题描述】:

我有多个线程通过我的 svc 对象记录一些信息。

public class SomeObject implements Runnable {
    @Override
    public void run() {
        ...
        svc.log("Reading file ...");
        .. some stuff...
        svc.log("Processing numbers ...");
        ... more stuff ...
        svc.log("Calculating power ...");
        ... and more stuff ...
    }
}

日志处理成本太高,所以我决定用另一个线程来做日志处理。 首先,我为每个日志操作创建了一个新线程。它更快,但我用完了内存。所以我决定创建一个只记录消息的单例线程。它更快并且使用更少的内存,但现在我遇到了一个新问题:正在以其他顺序写入日志...... 有时我有

Calculating power...
Reading file...
Processing numbers ...

而不是

Reading file...
Processing numbers ...
Calculating power...

我尝试使用BlockingQueue,所以改为直接登录,我将消息放入队列中,然后读取并记录其中的消息,但我对顺序有同样的问题。

我有另一个想法:将消息放入同步集合中,通过变量指定顺序并根据变量弹出元素,但这听起来很奇怪。

有什么想法可以继续使用线程并保持订单插入?

【问题讨论】:

  • 为什么不直接使用 log4J 之类的日志库?
  • 你怎么能使用阻塞队列并获得无序的消息?如果您使用的是 FIFO 方法,那么您的消息如何在队列中处于无序状态?会不会是你把消息放在队列本身的混乱中?
  • 归根结底,如果您正在运行多线程代码,则不再存在“之前”和“之后”,除非您强制线程相互等待。因此,无论您使用什么数据结构来记录日志调用,您都会以任意顺序获取消息。除非您自己打电话订购。
  • 然后使用 PriorityQueue 代替 BlockingQueue 并确保消息按时间戳排序/比较。每条消息在创建时和放入 PriorityQueue 之前都会获得一个时间戳。然后,无论它们来自哪里,它们都会以“正确的顺序”被消耗掉。
  • @EdwinDalorzo 我读过PriorityBlockingQueue(因为我需要“阻塞”行为),也许这可能是一个解决方案。我会尽快尝试的

标签: java multithreading collections


【解决方案1】:

您可以将消息放在ConcurrentSkipListSet 中,这是线程安全的,并且将根据元素的自然顺序或比较器(例如它们的时间戳)保持元素排序。还有一个ConcurrentSkipListMap,它根据键的自然顺序进行排序。

【讨论】:

  • 时间戳也不会强制执行“正确”顺序,首先它们的分辨率有限,其次,问题似乎是“自然”顺序不是 OP 想要的。跨度>
猜你喜欢
  • 2013-07-22
  • 2017-12-23
  • 1970-01-01
  • 2018-04-17
  • 2017-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-19
相关资源
最近更新 更多