場景1:
乙個方法中先查詢表中最新的一條資料,然後根據這條資料的值新增另一條資料:
public test1po testtransactional3()
select id, status, value
from test1
order by id desc
limit 1;
由於該方法本身就不是乙個原子操作,即存在多執行緒安全問題,所以給這個方法先加鎖:
public test1po testtransactional3()
}
另乙個方法中直接新增一條資料:
public test1po testtransactional2()
insert into test1(status, value)
values (#, #);
多執行緒測試:
public void testtransactional1()
} catch (interruptedexception | brokenbarrierexception e)
}, "t1").start();
new thread(() ->
} catch (interruptedexception | brokenbarrierexception e)
}, "t2").start();
new thread(() ->
} catch (interruptedexception | brokenbarrierexception e)
}, "t3").start();
}
t1和t2測試的是testtransactional3()方法本身的執行緒安全情況,由於通過synchronized加鎖,所以t1和t2之前沒有執行緒安全問題。
t1、t2和t3測試的是testtransactional3()方法和testtransactional2()方法同時執行的時候的執行緒安全情況,結果如下圖所示:
預期的正確情況應該是a0b這條資料應該在a1這條資料的前面。
解決方案1:
讓testtransactional3()方法和testtransactional2()方法對同乙個物件進行加鎖:
public test1po testtransactional2()
}public test1po testtransactional3()
}
結果如下圖所示:
解決方案2:
讓testtransactional3()方法執行帶where的insert:
public test1po testtransactional2()
@override
@transactional(rollbackfor = exception.class)
public test1po testtransactional3()
}
insert into test1(status, value)
select #, #
from dual
where exists (select 1 from dual where (select id from test1 order by id desc limit 1) = #);
結果如下圖所示:
問題在於insert可能不成功,這時候需要做另外的操作。
多執行緒安全問題
這裡的安全問題可以理解為 實現在邏輯上的問題,比如 火車站賣票 100張票讓4個人去賣,一定不能出現賣的票是負數問題,那麼開啟多執行緒後,如何才能保證賣的票不可能存在負數呢?常用的解決方法有兩種 1,使用同步 塊,把需要同步的 再放同步 塊中 2,使用同步函式 同步的鎖,可以理解為就是那個物件!同步...
多執行緒(多執行緒的安全問題)
多執行緒的執行出現安全問題。非常可怕的問題,一出問題比較惱火 問題原因 重點 當多條語句在操作同乙個執行緒共享資料時,乙個執行緒對多條語句只執行了一部分,還沒執行完,另乙個執行緒參與進來執行。導致共享資料的錯誤。解決方法 對多條操作共享資料的語句,只能讓乙個執行緒都執行完,在執行過程中,其他執行緒不...
多執行緒的安全問題
首先先提出幾個問題 1.多執行緒程式設計何時會出現執行緒不安全的問題?2.如何解決執行緒不安全的問題?執行緒不安全的本質是多執行緒共享資料,那麼什麼情況下多執行緒會共享資料?無外乎這麼幾種情況 1 多執行緒訪問單例項中的例項變數 2 多執行緒訪問靜態變數 下面將舉例說明,這個例子模擬鐵路售票系統,實...