【问题标题】:Handling concurrency in Liferay Cluster在 Liferay 集群中处理并发
【发布时间】:2016-05-17 16:39:07
【问题描述】:
【问题讨论】:
标签:
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() 应该找到持有真正锁的线程。
谢谢,
西比·马修