<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Loading

      【多線程】什么是悲觀鎖和樂觀鎖

      悲觀鎖

      概念

      悲觀鎖在已最壞的打算來考慮結果,它會在每次資源操作的同時,都需要對他進行加鎖,避免其他的線程來搶占。在絕對上保證我這次執行是沒有問題的。

      適用場景

      悲觀鎖適用于競爭激勵的場景,例如高并發的讀寫操作。

      典型案例

      synchronized 關鍵字

      public class TestLock implements Runnable{
      
          private static Object object = new Object();
      
          public static void main(String[] args) throws InterruptedException {
              Thread th01 = new Thread(new TestLock());
              Thread th02 = new Thread(new TestLock());
              th01.start();
              th02.start();
          }
      
          @Override
          public void run() {
              synchronized (object){
                  System.out.println(Thread.currentThread().getName()+"獲取到了鎖");
                  try {
                      TimeUnit.SECONDS.sleep(1);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
              System.out.println(Thread.currentThread().getName()+"釋放了鎖");
          }
      }
      

      輸出結果

      Thread-0獲取到了鎖
      Thread-0釋放了鎖
      Thread-1獲取到了鎖
      Thread-1釋放了鎖
      

      可以看到
      當線程Thread-0獲取到鎖的時候,Thread-1會陷入到阻塞狀態,因為這個時候synchronized發揮的是悲觀鎖,所以Thread-0在執行進入到鎖的同時,其他線程是無法獲取到鎖的狀態的

      Lock 接口

      public class TestLock implements Runnable{
      
          private static Lock lock = new ReentrantLock();
      
          public static void main(String[] args) throws InterruptedException {
              Thread th01 = new Thread(new TestLock());
              Thread th02 = new Thread(new TestLock());
              th01.start();
              th02.start();
          }
      
          @Override
          public void run() {
              lock.lock();
              System.out.println(Thread.currentThread().getName()+"獲取到了鎖");
              try {
                  TimeUnit.SECONDS.sleep(1);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              lock.unlock();
              System.out.println(Thread.currentThread().getName()+"釋放了鎖");
          }
      }
      

      Lock與synchronized的作用是一樣的,都是悲觀鎖,但是Lock的優勢要比
      synchronized強。平時我們要實現一個悲觀鎖,推薦使用Lock來使用。具體的優勢可以我這里就不再過多的闡述,后續會再會出一片這個文章來專門講。

      樂觀鎖

      概念

      樂觀鎖在Java的線程中,并不會真正的上鎖,而是通過以判斷初始值的方式來判斷當前操作的線程是否有被其他線程來操作過,當樂觀鎖判斷本次執行結束后發現初始值和當時開始執行的初始值一致的時候,那么就代表這次線程執行中,修改的值沒有被其他線程修改過,如果不一致那么就是被修改過。

      適用場景

      樂觀鎖適用于讀比較多,但是寫操作比較少的情況,并且并發也不會很高的時候。

      典型案例

      原子類

      AtomicInteger

      public class TestLock{
      
          private static AtomicInteger integer = new AtomicInteger(0);
      
          public static void main(String[] args) throws InterruptedException {
              Thread th01 = new Thread(()->{
                  while (integer.get()<10000){
                      System.out.println(Thread.currentThread().getName()+"輸出"+integer.addAndGet(1));
                  }
              });
              Thread th02 = new Thread(()->{
                  while (integer.get()<10000){
                      System.out.println(Thread.currentThread().getName()+"輸出"+integer.addAndGet(1));
                  }
              });
              th01.start();
              th02.start();
              th01.join();
              th02.join();
              System.out.println(integer.get());
          }
      }
      

      上面這段代碼其實就是簡單的實現了一個類似于i + + 的操作,但是為什么需要用到
      AtomicInteger來代替i + + 來實現呢,使用i + + 豈不是更簡單快捷一點的嗎?其實這里用AtomicInteger的原因就是因為i + + 它不是原子操作,在多線程的環境下會出現少加的情況,但是AtomicInteger就不一樣,他是基于CAS算法來實現樂觀鎖的,并且保證了每次在進行i + + 的情況下會得倒自己想要的值,接下來我們可以來看一下AtomicInteger的實現 + + i的流程。
      image.png
      在AtomicInteger的代碼中,是通過調用compareAndSwapInt方法來實現上面這個流程的,這個方法用了一種比較并交換的機制(Compare And Swap),在這個方法中有幾個參數:

      var1:傳入AtomicInteger對象
      var2:AtomicInteger中變量的偏移地址
      var5:修改之前的AtomicInteger中的值
      var5+var4:預期結果
      

      在compareAndSwapInt開始執行的時候,會先根據傳入的AtomicInteger對象和AtomicInteger中變量的偏移地址來獲取現在AtomicInteger內存中保存的正確的值,然后和修改之前獲取到的AtomicInteger值比較,如果一致那么就開始執行var5+var4,獲取預期結果,如果不一致,就會重頭再來。

      ++例如上面的流程,我們再用文字闡述一遍++
      步驟一:初始的AtomicInteger的值為0
      步驟二:線程A開始執行,獲取到AtomicInteger的值為0;
      步驟三:線程A執行暫停,線程B開始獲取AtomicInteger的值為0;
      步驟四:線程B開始執行 + +
      i操作,獲取到值為1,并修改了AtomicInteger的值
      步驟五:線程B執行完畢,切換到線程A。
      步驟六:線程A開始執行 + + i操作,這個時候線程A會再獲取一次AtomicInteger的值,發現AtomicInteger的值為1,與修改之前獲得的AtomicInteger的值0不同了。比較失敗,返回false,繼續循環。直到下次只執行的AtomicInteger的值等于修改之前的值,便執行成功。

      posted @ 2022-01-30 23:54  鄧小白  閱讀(157)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 深夜精品免费在线观看| 国产初高中生粉嫩无套第一次| 亚洲精品中文字幕尤物综合| 欧美丰满熟妇bbbbbb| 日韩亚洲国产中文字幕欧美| 国产乱码日产乱码精品精| 日本一区二区三区有码视频| 国产免费视频一区二区| 日本无人区一区二区三区| 国产欧美丝袜在线二区| 欧美精品国产综合久久| 日韩精品国产二区三区| 国偷自产av一区二区三区| 少妇爽到呻吟的视频| 日韩有码中文在线观看| 国产日本一区二区三区久久| 中文字幕av国产精品| 国产成人高清精品亚洲| 国产一区二区三区精品综合| 亚洲精品国产福利一区二区| 久久一日本综合色鬼综合色| 国产91午夜福利精品| 贵德县| 日本国产精品第一页久久| 野外做受三级视频| 人妻av无码系列一区二区三区| 国内揄拍国内精品对久久| 又粗又大又硬又长又爽| 亚洲精品成a人在线观看| 久久精品手机观看| 99久久精品费精品国产一区二| 蜜臀98精品国产免费观看| 婷婷精品国产亚洲av在线观看| 一区二区亚洲人妻精品| 精品国产一区二区三区国产区| 久久精品国产亚洲av忘忧草18| 亚洲国产精品综合久久20| 久久国产精品伊人青青草| 亚洲伊人久久精品影院| 无码免费大香伊蕉在人线国产| 亚洲av成人一区在线|