Java同步、信号量和队列的性能

Java同步、信号量和队列的性能,java,multithreading,synchronization,critical-section,Java,Multithreading,Synchronization,Critical Section,我正在编写一小段代码,将由多个线程同时调用,以收集进程的统计信息。代码简短而快速,但必须以某种方式同步以保持统计信息正确。典型负载约为每秒100-200个呼叫,但在一天中的某个时间点,可能会升级到每秒5000个呼叫 synchronized是否会减慢处理速度?如果我有16个内核而不是4个,那么处理更多的内核会变得更昂贵吗 // This method is called by multiple threads public synchronized void record(String al

我正在编写一小段代码,将由多个线程同时调用,以收集进程的统计信息。代码简短而快速,但必须以某种方式同步以保持统计信息正确。典型负载约为每秒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)
     }
    
  • 我考虑的另一个选择是使用
    信号量
    访问关键部分。它们比选项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();
       }
     }
    
  • 最后,我考虑了一个队列(每个调用方都是生产者+一个
    执行者
    作为消费者),但我希望避免额外的线程/执行者作为消费者

  • 还有更好的选择吗


  • 最后但并非最不重要的一点是,对于每秒5000次呼叫的用例,我是否担心得太多了?如果是这样的话,我会使用最简单的选项(同步方法)来控制并发性。

    如果您的计算又短又快,那么使用信号量vs synchronized并不会给您带来什么好处。对于消息的并发处理,生产者/消费者是最佳选择。您可以使用阻塞队列,然后旋转多个使用者线程。

    不知道您在做什么。若并没有更好的描述,就并没有人能够回答。闻起来像测微计之类的东西可能已经解决了。如果没有,通常的方法是线程将其更新发布到异步队列,并有一个使用它的更新程序线程。@chrylis小心地优化-感谢您的回复。我在看千分尺。。。想知道如何为stats指定需要实现的自定义逻辑。我将继续阅读。我看不出有任何理由超越这里的
    synchronized
    。您的第二个示例同时使用了
    synchronized
    Semaphore
    ,这是没有意义的。队列肯定只会让事情变得更糟,因为无论是添加到队列还是从队列中删除,您都需要同步或同步。@使用合适的(阻塞)队列将为您解决大多数问题。