【发布时间】:2020-09-11 01:31:41
【问题描述】:
我正在编写一小段代码,它将被多个线程同时调用以收集有关进程的统计信息。代码简短而快速,但必须以某种方式同步以保持统计数据正确。典型负载约为每秒 100-200 个调用,但在一天中的某个时间点可能会升级到每秒 5000 个调用。
-
synchronized处理这个速度慢吗?如果我有 16 个内核而不是 4 个内核,那么处理我拥有的更多内核是否会变得更昂贵?// This method is called by multiple threads public synchronized void record(String alias, long result, int delta) { // compute custom stats here... (short & quick) } -
我正在考虑的另一个选项是使用
Semaphore来访问临界区。它们比选项#1 快吗?他们还在幕后使用锁吗?private Semaphore s = new Semaphore(1); public void record(String alias, long result, int delta) throws InterruptedException { boolean acquired = false; try { this.s.acquire(); acquired = true; // compute custom stats here... (short & quick) } finally { if (acquired) this.s.release(); } } -
最后,我正在考虑一个队列(每个调用者是一个生产者 + 一个
Executor作为消费者),但我想避免一个额外的线程/执行者作为消费者。 -
其他更好的选择?
最后但同样重要的是,对于我每秒 5000 次调用的用例,我是否过于担心?如果是这样,我会使用最简单的选项(同步方法)来控制并发。
【问题讨论】:
-
不知道你在做什么。没有更好的描述,没有人能够回答。
-
闻起来像 Micrometer 之类的东西可能已经解决了。如果没有,通常的方法是让线程将它们的更新发布到异步队列,并有一个单独的更新线程来消费它。
-
@chrylis-cautiouslyoptimistic- 感谢您的回复。我在看千分尺......想知道如何指定我需要为统计数据实现的自定义逻辑。将继续阅读。
-
我看不出有任何理由超越
synchronized。您的第二个示例同时使用了synchronized和Semaphore,这没有意义。队列肯定只会让事情变得更糟,因为在添加队列和从中删除队列时都需要同步或信号量。 -
@MarquisofLorne 使用合适的(阻塞)队列将为您解决大部分问题。
标签: java multithreading synchronization critical-section