Java同步、信号量和队列的多线程性能
我正在编写一小段代码,将由多个线程同时调用,以收集进程的统计信息。代码简短而快速,但必须以某种方式同步以保持统计信息正确。典型负载约为每秒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次呼叫的用例,我是否担心得太多了?如果是这样,我将使用最简单的选项(同步方法)来控制并发性
# 1 楼答案
如果您的计算又短又快,那么使用信号量vs synchronized并不能真正为您提供线索。对于消息的并发处理,生产者/消费者是最佳选择。您可以使用阻塞队列,然后旋转多个使用者线程