我是多線程的新手,我有一些基本問題無法得到答案。假設我有一個名為 BankTransaction 的類,我想在其中處理多線程情況。案例 1(基于應用程序的單例)@Singleton (Application based singleton)class BankTransaction { synchronized void doSomeTransaction() { // write operation }}案例 2(基于請求的單例)@Singleton (Request based singleton)class BankTransaction{ synchronized void doSomeTransaction() { // write operation }}問題請耐心等待并以通俗易懂的方式向我解釋,因為我需要把事情弄清楚。在案例 1 中,如果 1000 個用戶正在使用 BankTransaction 類的同一個實例(因為它是基于應用程序的單例)并使用方法 doSomeTransaction(),這 1000 個用戶中的每個用戶的請求會很慢嗎?因為它是同步的并且可以線程安全地工作。所以,這是不好的方法。我的理解正確嗎?在案例 2 中,如果同樣的 1000 個用戶正在使用 BankTransaction 類的 doSomeTransaction() 方法,每個人都將獲得他們自己的 BankTransaction 類的實例,并且對他們中的任何一個來說都不會慢。但是,例如,在這 1000 個用戶中,其中 2 個是密切相關的(丈夫和妻子)并且正在訪問同一個銀行帳戶并同時執行 doSomeOperation() 方法時,我該如何處理競爭條件。我該如何處理?因為它們都有 2 個不同的類 BankTransaction 實例,并且會發生數據不一致。
2 回答

撒科打諢
TA貢獻1934條經驗 獲得超2個贊
是的。你的理解是正確的。如果您不想以某種方式允許多個用戶更改對象的狀態,則應該使方法同步。該示例可以是應用程序級配置對象。
現在,有很多解決方案。最簡單的方法是將此問題推遲到某些 ORM 解決方案,該解決方案可以進一步使用記錄級鎖定技術或其他任何技術。但是,如果您想手動處理這個問題,最簡單的方法是在 db 中維護一個列。現在,每次修改記錄時,都應該增加該值。在提交記錄之前,您應該檢查該值是否與您從數據庫中獲取的記錄的值相同。如果相同,那么您可以確定自您開始交易以來沒有人修改過它。但是,如果值不相同,您可以向用戶拋出一個錯誤,說記錄已被其他用戶修改。

HUX布斯
TA貢獻1876條經驗 獲得超6個贊
在第一種情況下,1000 個用戶(或他們的線程)將等待很長時間,因為一次只有一個人可以訪問該方法。所有其他人都必須等待鎖定才能訪問此方法。所以,是的,它會很慢。
如果每個用戶都有自己的 BankTransaction 類實例,它不會很慢,因為方法上的鎖是針對一個對象的(鎖對象在這個實現中是“this”)。因此,用戶(或他們的線程)只有在有另一個用戶想要對完全相同的對象使用相同的方法時才會等待(如果每個用戶都有自己的實例,情況就不應該如此)。
添加回答
舉報
0/150
提交
取消