java实现表锁行锁
生活随笔
收集整理的這篇文章主要介紹了
java实现表锁行锁
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
背景
今天做需求時遇到一個統計場景,接口將用戶請求記錄緩存在concurrentHashmap,其中用戶名作為map的Key,value為統計結果類的對象,更新此map的時候使用分段鎖(通過用戶名取hash值定位對應的鎖)確保在相對良好性能下使得value更新線程安全。此外通過定時任務2秒一次將緩存的map保存到redis數據庫后再清空map,這意味著定時任務執行的某個時候需要暫停所有寫入map操作,由于map寫入是使用分段鎖,意味著需要阻塞所有獲取分段鎖線程,類似于mysql某些修改表結構的時候會阻塞行鎖一樣。查閱資料后發現java并無相關實現,這里手動實現一個。
分段獨占鎖
行表鎖
測試代碼
public static void main(String[] args) {//測試行鎖釋放和未釋放情況下獲取表鎖testBlockingTableLock();//測試表鎖釋放和未釋放情況下獲取行鎖 // testBlockingRowLock();}//測試行鎖釋放和未釋放情況下獲取表鎖private static void testBlockingTableLock(){TableRowsLock tableLock = new TableRowsLock(2);new Thread(() -> {try {long stamp1 = tableLock.tryLockRow("1");System.out.println("未加表鎖與行鎖時獲取行鎖1,結果:" + stamp1);long stamp2 = tableLock.tryLockRow("2");System.out.println("未加表鎖只加行鎖時獲取行鎖2,結果:" + stamp2);TimeUnit.SECONDS.sleep(2);//釋放行鎖tableLock.unlockRow("1", stamp1);tableLock.unlockRow("2", stamp2);} catch (Exception ex){ex.printStackTrace();}}).start();new Thread(() -> {try {TimeUnit.MILLISECONDS.sleep(500);//獲取表鎖long stamp = tableLock.tryLockTable();System.out.println("行鎖未釋放,獲取表鎖,結果:" + stamp);TimeUnit.SECONDS.sleep(3);stamp = tableLock.tryLockTable();System.out.println("行鎖全部釋放后 再次獲取表鎖,結果:" + stamp);} catch (InterruptedException e) {e.printStackTrace();}}).start();}//測試表鎖釋放和未釋放情況下獲取行鎖private static void testBlockingRowLock(){TableRowsLock tableLock = new TableRowsLock(2);new Thread(() -> {try {long stamp = tableLock.tryLockTable();System.out.println("未加行鎖時獲取表鎖,結果:" + stamp);TimeUnit.SECONDS.sleep(2);//釋放表鎖tableLock.unLockTable(stamp);} catch (Exception ex){ex.printStackTrace();}}).start();new Thread(() -> {try {TimeUnit.MILLISECONDS.sleep(500);//獲取行鎖long stamp = tableLock.tryLockRow("1");System.out.println("表鎖未釋放,獲取行鎖,結果:" + stamp);//表鎖釋放后獲取行鎖TimeUnit.SECONDS.sleep(3);stamp = tableLock.tryLockRow("1");System.out.println("表鎖釋放后,再次獲取行鎖,結果:" + stamp);} catch (Exception e) {e.printStackTrace();}}).start();}總結
以上是生活随笔為你收集整理的java实现表锁行锁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java修改配置不重启,java运行时修
- 下一篇: webflux切面拦截权限,webflu