簡體   English   中英

使方法同步將確保它是線程安全的嗎?

[英]Is making a method synchronized will ensure that it is thread safe?

我有一種方法,其中一些數據庫插入操作正在使用休眠進行,我希望它們是線程安全的。 該方法以參數為單位獲取某些數據,並且有可能有時在同一時間點使用相同數據進行兩次調用。

由於性能下降,我無法鎖定這些表。 誰能建議使該方法成為同步方法可以解決問題?

同步方法將確保一次只能由一個線程訪問該方法。 如果此方法是您寫入數據庫的唯一方法,那么可以,這將阻止兩個線程同時寫入。 但是,您仍然必須處理這樣一個事實,即您需要對同一數據執行多個插入操作。

您應該讓Hibernate處理並發,這就是要做的事情。 不要以為Hibernate會鎖定任何東西:為此,它支持樂觀事務 從以上鏈接引用:

與高並發性和高可伸縮性一致的唯一方法是通過版本控制進行樂觀並發控制。 版本檢查使用版本號或時間戳來檢測沖突的更新並防止更新丟失。 Hibernate提供了三種使用樂觀並發編寫應用程序代碼的方法。

數據庫並發由事務處理。 事務具有“原子一致性持久隔離(ACID)”屬性。 它們提供了並發訪問數據庫的程序之間的隔離。 在spring框架的Hibernate DAO模板中,有用於數據庫上CRUD操作的單行方法。 單獨使用時,不需要按方法進行同步。 如果您需要使用特定的傳播設置,rollbackFor設置,隔離設置將“您的方法”聲明為事務性的,則Spring提供了聲明式(XML),程序化和注釋元數據驅動的事務管理。 因此,在“您的方法”中,您可以進行多次保存,更新,刪除等操作,並且ORM將確保使用您在元數據中給定的事務設置執行該操作。

另一個問題是線程必須鎖定參與事務的所有對象,否則事務可能會失敗或ORM將保留陳舊數據。 在另一種情況下,由於鎖定順序,可能導致死鎖。 我認為這才是真正回答您問題的方法。

對象a和b都有一個Lock類型的實例變量。 布爾標志可用於指示交易成功。 如果客戶端代碼失敗,則可以重試同一事務。

             if (a.lock.tryLock()) {
                try {
                    if (b.lock.tryLock()) {
                        try {
                            // persist or update object a and b
                        } finally {
                            b.lock.unlock();
                        }
                    }
                } finally {
                    a.lock.unlock();
                }
            }

使用同步方法的問題在於,它鎖定了整個Service或DAO類,從而使其他線程無法使用其他服務方法。 通過對對象使用單獨的鎖,我們可以獲得細粒度並發的優勢。

不可以。此方法可能使用其他方法和對象,這些方法和對象可能不是線程安全的。 synchronized使線程一次只能使用該方法的對象monitor一次,因此它使線程安全的方法相對於該對象。

如果確定所有其他線程僅通過此方法使用共享功能,則使其synchronized可能就足夠了。

選擇最佳策略取決於體系結構,有時使用方法同步之類的技巧來提高性能似乎更容易,但這是不好的方法。

毫無疑問,您應該使用事務,並且如果使用該策略遇到性能問題,則應該優化數據庫查詢或數據庫結構。

請記住,“同步”應盡可能地原子。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM