【问题标题】:How to perform with longadder如何使用 longadder 执行
【发布时间】:2021-07-05 23:02:09
【问题描述】:

您好,我有一个应用程序计算时间并据此引发事件。我想使用 longadder 或任何合适的方法使我的应用程序具有线程安全性。

下面是我的班级;

    @Autowired
    EventListenerConfiguration eventListenerConfiguration;

    private volatile long lastReceivedMessage = System.currentTimeMillis();

 
    public void consume(String message) Integer partition,
                        (Headers.OFFSET) Long offset, Acknowledgment ack) {


        lastReceivedMessage = System.currentTimeMillis();

        try {
            seervice.processMessage(message, ack, null);

        } catch (ParseException e) {
            logger.error(e.getMessage());
        }
    }

    @Scheduled(fixedDelayString = "${listenScheduled}", initialDelay = 100000)
    private void distanceBetweenLastReceivedMessageAndCurrentTime() {

        long currentTime = System.currentTimeMillis() - lastReceivedMessage;

        if (currentTime >= EventListenerConfiguration .getTotalMilliSecondTimeForError()) {

            EventUtil.publishEvent(THROW_ERROR_EVENT, EventSeverityStatus.ERROR, EventTypeStatus.CUSTOM, null);


        } else (currentTime >= EventListenerConfiguration.getTotalMilliSecondTimeForWarn()) {

            EventUtil.publishEvent(THROW_WARN_EVENT, EventSeverityStatus.WARN, EventTypeStatus.CUSTOM, null);

        }
}

所以基本上如何在不改变 longAdder 的情况下转换我的代码并执行 currentTime-lastReceiveMessage

谢谢

【问题讨论】:

  • 你好@John deltana,看起来你正在使用 Spring 应用程序来调用你的代码。您提到它不是以线程安全的方式运行的。了解观察到的行为是有帮助的。在提出解决方案之前,我们可能需要更多背景信息。
  • 感谢您的重播,我只是想防止我的事件在我必须用我的 yml 设置的计时器上被破坏我也尝试了 volatile 方法,如果这对这种情况有帮助的话

标签: java spring multithreading java-8 thread-safety


【解决方案1】:

晚上好。看来您的问题主要是 lastReceivedMessage 是两个线程使用的受保护资源。无论运行什么,consume 方法都会生成它,然后 Spring-Generated @scheduled 线程会消耗它。

添加 volatile 关键字不会阻止代码读取该字段。它只会阻止代码缓存变量。 (继续阅读 volatile https://www.geeksforgeeks.org/volatile-keyword-in-java/)如果您想将 @Scheduled 块视为关键区域,并在完成之前阻止 lastRecievedMessage 的更新,我建议您执行以下操作:

    private volatile long lastReceivedMessage = System.currentTimeMillis();
    private Semaphore resourceLock = new Semaphore(1);

    public void consume(String message) Integer partition,
    (Headers.OFFSET) Long offset, Acknowledgment ack) {

        resourceLock.acquireUninterruptibly();
        try {
            lastReceivedMessage = System.currentTimeMillis();
        } finally {
            resourceLock.release();
        }

        try {
            seervice.processMessage(message, ack, null);

        } catch (ParseException e) {
            logger.error(e.getMessage());
        }
    }

    @Scheduled(fixedDelayString = "${listenScheduled}", initialDelay = 100000)
    private void distanceBetweenLastReceivedMessageAndCurrentTime() {
        long currentTime = 0;

        resourceLock.acquireUninterruptibly();
        try {
                currentTime = System.currentTimeMillis() - lastReceivedMessage;
                
            if (currentTime >= EventListenerConfiguration .getTotalMilliSecondTimeForError()) {
                EventUtil.publishEvent(THROW_ERROR_EVENT, EventSeverityStatus.ERROR, EventTypeStatus.CUSTOM, null);

            } else (currentTime >= EventListenerConfiguration.getTotalMilliSecondTimeForWarn()) {
                EventUtil.publishEvent(THROW_WARN_EVENT, EventSeverityStatus.WARN, EventTypeStatus.CUSTOM, null);
            }
        } finally {
            resourceLock.release();
        }
    }

【讨论】:

  • @John Deltana,如果这不是您遇到的问题,那么您的问题需要更加明确。
  • 这正是我想要的,非常有启发性。非常感谢
猜你喜欢
  • 2021-05-29
  • 2015-08-21
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-10
相关资源
最近更新 更多