我們的應用程序運行在WebLogic 12c中,它正在從排隊系統中檢索消息,其中我們檢索消息的隊列被配置爲FIFO。我們使用Spring來配置檢索功能,並且容器(org.springframework.jms.listener.DefaultMessageListenerContainer)和消息監聽器(org.springframework.jms.core.support.JmsGatewaySupport)都是單例。此外,該容器默認將工作管理器配置爲任務執行程序。爲了保證消息按照預期的順序處理(它們被髮送到隊列的順序),我們在監聽器中使用ReentrantLock,並且我們期望消息被逐個檢索和處理。聽者代碼是下列之一:線程獲取已被其他線程獲取的ReentrantLock
public class JmsReceiveAdapterImpl extends JmsGatewaySupport implements SessionAwareMessageListener {
private final ReentrantLock lock = new ReentrantLock(true);
[...]
public void onMessage(Message rcvMessage, Session session) throws JMSException {
lock.lock();
logger.warn("Lock has been acquired by thread: " + Thread.currentThread().getId());
try {
[...]
} finally {
logger.warn("Lock is going to be released by thread: " + Thread.currentThread().getId());
lock.unlock();
}
}
}
即使兩個消息被放置在隊列中以正確的順序,它們被消耗的順序(召回該隊列是一個FIFO之一),以某種方式在兩個消息由應用程序並行處理,如以下日誌塊所示:
Lock has been acquired by thread: 28 Backout count: 1 Message 1/1 received from XXX Message ID1 received. Lock has been acquired by thread: 54 Backout count: 1 Message 1/1 received from XXX Message ID2 received. ***** ERROR ***** Lock is going to be released by thread: 54 Lock is going to be released by thread: 28
爲什麼我們要獲得此行爲?任何想法?
非常感謝你的進步。
考慮到'ReentrantLock'不工作的機會接近零,我建議你輸出'this'到日誌,以確保你的班級是一個單身人士。 – user3707125
同時檢查你是否在這個鎖創建的某些條件下不調用'await()'。 – talex
如果你想絕對確定,你可以將鎖定爲靜態,但是從設計的角度來看,這將是一場災難 –