2015-06-21 22 views
1

讓我們線程安全類像LinkedBlockingDeque如何編寫線程安全操作並使它們成爲原子?

BlockingQueue<Task> taskQueue = new LinkedBlockingDeque<Task>(); 

我知道,像takeput操作是線程安全的,所以他們尊重之前發生的關係。

但是如果我想編寫一些操作使它們成爲原子呢? 像這樣:

if(taskQueue.size() == 1) { 
    /*Do a lot of things here, but I do not want other threads 
    to change the size of the queue here with take or put*/ 
} 
//taskQueue.size() must still be equal to 1 

如果它是不是線程安全類,我可以做這樣的事情:

synchronized(taskQueue) { 
    if(taskQueue.size() == 1) { 
    /*Do a lot of things here, but I do not want other threads 
     to change the size of the queue here with take or put*/ 
    } 
    //taskQueue.size() must still be equal to 1 
} 

但它不是那麼簡單的,我不認爲的take的實現和put使用對象鎖。

你如何處理這個scanario?

+0

使用「正常」隊列和執行'synchronized'更容易。有更先進的技術,它們可能太複雜了,實際上可能並不比簡單的鎖定更快。 – ZhongYu

+0

感謝您的回答,但我的意思是構成java線程安全類(如LinkedBlockingDeque)的一些線程安全操作如此困難?我的情況非常普遍:我想有時會鎖定整個隊列以進行特定的操作,有時還會利用併發的取放。 – Kami

+0

您是否希望隊列保持未修改狀態,還是希望在不可修改的隊列快照上工作,而其他線程可以繼續更改原始隊列? –

回答

2

你如何處理這種情況?

一般來說,如果不使用某種外部鎖定,您無法對併發數據結構進行「組合」操作。當你這樣做時,你重新引入了你試圖通過使用併發數據結構避免的併發瓶頸。

在這種情況下,您是正確的。 LinkedBlockingDeque類使用專用鎖對象進行同步等。

+0

*當您這樣做時,您將通過使用併發數據結構*重新引入您試圖避免的併發瓶頸。從概念上講,我認爲並不清楚併發數據結構的目的。謝謝。 – Kami

相關問題