【问题标题】:Handling concurrency in Liferay Cluster在 Liferay 集群中处理并发
【发布时间】:2016-05-17 16:39:07
【问题描述】:

我在 LR 6.2 CE GA4 集群环境中工作。 2 个节点通过 portal-ext 集群配置共享同一个数据库和共享缓存。

我有一个调度程序每 15 分钟调用一次方法 processMe(),用户也可以在单击页面时调用该方法。

我的要求是限制对这个方法的并发调用。 我了解由于 JVM 不同,同步块无法正常工作。

有什么东西我可以在 Liferay 中重用 OOTB 吗? 我可以重用 JGroups 单播/多播通信中的某些内容吗?

还有其他建议吗?

发表于liferay论坛: https://web.liferay.com/community/forums/-/message_boards/message/74168121

谢谢,

西比·马修

【问题讨论】:

  • 您想从哪里得到答案?这里?或者在 Liferay 的论坛上?别处?请阅读meta.stackexchange.com/questions/141823/…并相应地更新/链接/删除
  • 我在 liferay 论坛中添加了我帖子的链接

标签: java concurrency locking liferay cluster-computing


【解决方案1】:

参考方法找到了解决办法:com.liferay.portal.kernel.backgroundtask.SerialBackgroundTaskExecutor.acquireLock()

代码如下:

    @Override
    public BackgroundTaskResult execute(BackgroundTask backgroundTask)
        throws Exception {

    Lock lock = null;

    String owner =
        backgroundTask.getName() + StringPool.POUND +
            backgroundTask.getBackgroundTaskId();

    try {
        if (isSerial()) {
            lock = acquireLock(backgroundTask, owner);
        }

        BackgroundTaskExecutor backgroundTaskExecutor =
            getBackgroundTaskExecutor();

        return backgroundTaskExecutor.execute(backgroundTask);
    }
    finally {
        if (lock != null) {
            LockLocalServiceUtil.unlock(
                BackgroundTaskExecutor.class.getName(),
                backgroundTask.getTaskExecutorClassName(), owner);
        }
    }
}  

 protected Lock acquireLock(BackgroundTask backgroundTask, String owner)
        throws DuplicateLockException {

    Lock lock = null;

    while (true) {
        try {
            lock = LockLocalServiceUtil.lock(
                BackgroundTaskExecutor.class.getName(),
                backgroundTask.getTaskExecutorClassName(), owner);

            break;
        }
        catch (SystemException se) {
            if (_log.isDebugEnabled()) {
                _log.debug("Unable to acquire acquiring lock", se);
            }

            try {
                Thread.sleep(50);
            }
            catch (InterruptedException ie) {
            }
        }
    }

    if (!lock.isNew()) {
        throw new DuplicateLockException(lock);
    }

    return lock;
}

我的代码的主要变化是检查

if (!lock.isNew()) {
 throw new DuplicateLockException(lock);
}

基本上,即使两个线程能够调用 lock() 方法(我正在通过同时触发两个调度程序进行测试),也只有一个线程会成功创建新对象,而另一个线程只会获取现有的锁对象。

因此 lock.isNew() 应该找到持有真正锁的线程。

谢谢,

西比·马修

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-23
    • 1970-01-01
    相关资源
    最近更新 更多