主要来自同一线程的方法调用的 Java 同步

我在一个具有可变状态的类中有一个方法,该方法从单个线程调用99.999%,除了一次从关闭钩子中的不同线程调用。


这是该类的骨架


public class StateHolder {

    private final Queue<String> q;


    public synchronized void add(String s) {

       this.q.offer(s);

       this.lastUpdateTime = System.currentTimeMillis();

    }


    public synchronized void removeUntil(Predicate<String> p) {

        while(!q.isEmpty()) {

           if (p.applies(q.peek()) {

                q.poll();

            } else {

                break;

            }

        }

        this.lastUpdateTime = System.currentTimeMillis();

    }


    public synchronized int pendingRecords() {

        return this.q.size();

    }


    public synchronized void shutdown(Consumer<String> c) {

        while(!q.isEmpty()) c.accept(q.poll());

    }

}

在上面的, 方法 ,并将始终在应用程序的生存期内从同一线程调用(每秒 1000 多次调用,具体取决于应用程序的流量)。在应用程序关闭期间,将由不同的线程调用,这将在几周内发生一次。addpendingRecordsremoveUntilshutdown


对于此访问模式,是否存在已知更适合性能的同步原语?或者我应该只使用传统的块并让JIT弄清楚吗?synchronized


PIPIONE
浏览 125回答 2
2回答

红糖糍粑

我相信你会利用(开箱即用)偏见锁定 -&nbsp;Java中的偏见锁定

跃然一笑

首先,您需要阐明对 的调用的语义,以及何时发生并发调用。在当前的实现中,这些调用将被阻止,直到返回,但之后它们将愉快地继续。也许在这种情况下扔一个会更好。但这实际上取决于您的要求。addpendingRecordsremoveUntilshutdownshutdownIllegalStateException为了改进并发性方面,我将生命周期问题与应用程序逻辑的其余部分分开。例如,您可以从 更改为 。然后,调用会将该引用设置为一个实现,该实现将表示正在进行的关闭,例如,在其所有方法上抛出。根据您需要的确切语义,还有其他与并发相关的问题需要解决。例如,在循环中途开始失败是可以的吗?如果不是,则该方法需要从输入该方法时获取的队列的本地副本进行操作。shutdownqQueue<String>AtomicReference<Queue<String>>shutdownQueueIllegalStateExceptionremoveUntil
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java