1. 程式人生 > >每天一例多執行緒[day21]-----ReentrantReadWriteLock

每天一例多執行緒[day21]-----ReentrantReadWriteLock

ReentrantReadWriteLock,讀寫鎖,核心就是實現讀寫分離的鎖,在高併發訪問下,尤其是讀多寫少的場景下,效能要遠遠高於重入鎖。之前的ReentrantLock和Synchronized在同一時間內只能有一個執行緒訪問被鎖定的程式碼,那麼讀寫鎖則不同,其本質時分成兩個鎖,讀鎖+寫鎖,在讀鎖下,多個執行緒可以併發地訪問;但是在寫鎖的時候只能一個一個順序訪問。

總結:讀讀共享,讀寫互斥,寫寫互斥。

  1. import java.util.concurrent.locks.ReentrantReadWriteLock;

  2. import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;

  3. import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;

  4. public class UseReentrantReadWriteLock {

  5. private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();

  6. private ReadLock readLock = rwLock.readLock();

  7. private WriteLock writeLock = rwLock.writeLock();

  8. public void read(){

  9. try {

  10. readLock.lock();

  11. System.out.println("當前執行緒:" + Thread.currentThread().getName() + "進入...");

  12. Thread.sleep(3000);

  13. System.out.println("當前執行緒:" + Thread.currentThread().getName() + "退出...");

  14. } catch (Exception e) {

  15. e.printStackTrace();

  16. } finally {

  17. readLock.unlock();

  18. }

  19. }

  20. public void write(){

  21. try {

  22. writeLock.lock();

  23. System.out.println("當前執行緒:" + Thread.currentThread().getName() + "進入...");

  24. Thread.sleep(3000);

  25. System.out.println("當前執行緒:" + Thread.currentThread().getName() + "退出...");

  26. } catch (Exception e) {

  27. e.printStackTrace();

  28. } finally {

  29. writeLock.unlock();

  30. }

  31. }

  32. public static void main(String[] args) {

  33. final UseReentrantReadWriteLock urrw = new UseReentrantReadWriteLock();

  34. Thread t1 = new Thread(new Runnable() {

  35. @Override

  36. public void run() {

  37. urrw.read();

  38. }

  39. }, "t1");

  40. Thread t2 = new Thread(new Runnable() {

  41. @Override

  42. public void run() {

  43. urrw.read();

  44. }

  45. }, "t2");

  46. Thread t3 = new Thread(new Runnable() {

  47. @Override

  48. public void run() {

  49. urrw.write();

  50. }

  51. }, "t3");

  52. Thread t4 = new Thread(new Runnable() {

  53. @Override

  54. public void run() {

  55. urrw.write();

  56. }

  57. }, "t4");

  58. //讀讀共享

  59. // t1.start();//R

  60. // t2.start();//R

  61. //讀寫互斥

  62. // t1.start(); // R

  63. // t3.start(); // W

  64. //寫寫互斥

  65. t3.start();//W

  66. t4.start();//W

  67. }

  68. }

分析:在兩個執行緒一起訪問的是一個被讀鎖鎖定的方法時,可以一起進入讀取資料,相當於資料是共享的。但是如果一個訪問的是讀鎖鎖定的方法,一個訪問的是寫鎖鎖定的方法,則相當於訪問的是同一把鎖,只能等一個訪問完釋放後,另外一個執行緒才能繼續訪問,寫寫亦然。