为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

PIPIONE 2022-09-14 10:32:50
我在一个具有可变状态的类中有一个方法,该方法从单个线程调用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
查看完整描述

2 回答

?
红糖糍粑

TA贡献1815条经验 获得超6个赞

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


查看完整回答
反对 回复 2022-09-14
?
跃然一笑

TA贡献1826条经验 获得超6个赞

首先,您需要阐明对 的调用的语义,以及何时发生并发调用。在当前的实现中,这些调用将被阻止,直到返回,但之后它们将愉快地继续。也许在这种情况下扔一个会更好。但这实际上取决于您的要求。addpendingRecordsremoveUntilshutdownshutdownIllegalStateException

为了改进并发性方面,我将生命周期问题与应用程序逻辑的其余部分分开。例如,您可以从 更改为 。然后,调用会将该引用设置为一个实现,该实现将表示正在进行的关闭,例如,在其所有方法上抛出。根据您需要的确切语义,还有其他与并发相关的问题需要解决。例如,在循环中途开始失败是可以的吗?如果不是,则该方法需要从输入该方法时获取的队列的本地副本进行操作。shutdownqQueue<String>AtomicReference<Queue<String>>shutdownQueueIllegalStateExceptionremoveUntil


查看完整回答
反对 回复 2022-09-14
  • 2 回答
  • 0 关注
  • 74 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信