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

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

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

      技術面:Java并發(線程同步、死鎖、多線程編排)

      線程同步的方式有哪些?

      線程同步

      線程同步,是多線程編程中的一種機制,用于協調多個線程的執行順序,確保它們在共享資源或關鍵操作上按照預定的規則運行,避免因并發訪問導致的數據不一致、競態條件(Race Condition)等問題。

      線程同步的方式有哪些?

      1. synchronized 關鍵字,通過 JVM 內置的鎖機制實現線程同步,確保同一時刻只有一個線程訪問共享資源。既可以修飾實例方法也可以修飾靜態方法,也可以鎖代碼塊和鎖住某個具體的實例對象
      public synchronized void method() { ... } // 實例方法鎖(this)
      public static synchronized void method() { ... } // 類方法鎖(Class 對象)
      // 鎖實例對象
      synchronized (lockObject) {
          // 同步代碼塊
      }
      
      1. ReentrantLock 基于 java.util.concurrent.locks.Lock 接口實現的可重入互斥鎖,需顯式調用 lock()unlock()進行加鎖和解鎖。
        支持公平鎖、可中斷鎖、超時鎖以及多條件變量(Condition),相比 synchronized 提供了更高的靈活性。
      ReentrantLock lock = new ReentrantLock();
      lock.lock();
      try {
          // 同步代碼
      } finally {
          lock.unlock();
      }
      
      1. Semaphore(信號量),允許多個線程同時訪問資源,但是限制訪問線程的數量。
      Semaphore semaphore = new Semaphore(3); // 初始許可數為3
      semaphore.acquire(); // 獲取許可
      try {
          // 同步代碼
      } finally {
          semaphore.release(); // 釋放許可
      }
      
      1. CountDownLatch,允許多個線程等待其他線程執行完畢之后再執行,用于線程間的協作。
      public class LatchDemo {
          public static void main(String[] args) throws InterruptedException {
              int threadCount = 3;
              CountDownLatch latch = new CountDownLatch(threadCount);
      
              for (int i = 1; i <= threadCount; i++) {
                  new Thread(() -> {
                      System.out.println(Thread.currentThread().getName() + " 初始化完成");
                      latch.countDown(); // 子線程完成,計數器減 1
                  }, "線程-" + i).start();
              }
      
              latch.await(); // 主線程等待所有子線程完成
              System.out.println("所有子線程完成,主線程繼續執行");
          }
      }
      
      1. CyclicBarrier,多個線程互相等待,所有線程都到到屏障點后,再繼續執行。線程計數器可重置。
      import java.util.concurrent.BrokenBarrierException;
      import java.util.concurrent.CyclicBarrier;
      import java.util.concurrent.ExecutorService;
      import java.util.concurrent.Executors;
      
      public class CyclicBarrierExample {
          // 總和變量(線程安全)
          private static int sum = 0;
          // 線程池
          private static final ExecutorService executor = Executors.newFixedThreadPool(5);
      
          public static void main(String[] args) {
              // 定義需要等待的線程數量(5個)
              CyclicBarrier cyclicBarrier = new CyclicBarrier(5, () -> {
                  // 所有線程到達屏障后執行的回調(匯總結果)
                  System.out.println("所有線程已完成計算,總和為: " + sum);
              });
      
              // 啟動5個線程
              for (int i = 0; i < 5; i++) {
                  executor.execute(() -> {
                      try {
                          // 模擬線程計算
                          int value = (int) (Math.random() * 100);
                          System.out.println(Thread.currentThread().getName() + " 計算值: " + value);
                          // 將計算結果累加到總和中
                          sum += value;
      
                          // 調用await()等待其他線程到達屏障
                          cyclicBarrier.await();
                      } catch (InterruptedException | BrokenBarrierException e) {
                          e.printStackTrace();
                      }
                  });
              }
      
              // 關閉線程池
              executor.shutdown();
          }
      }
      
      1. Phaser,和CyclicBarrier類似,但是支持更靈活的屏障操作,適用于復雜多階段任務,支持動態注冊/注銷參與者,并可控制各參與者的階段進度,并可以控制各個參與者的到達和離開。
      Phaser phaser = new Phaser(1); // 初始參與線程
      phaser.bulkRegister(3);        // 動態注冊3個工作線程
      
      for (int i = 0; i < 3; i++) {
          new Thread(() -> {
              for (int phase = 0; phase < 2; phase++) {
                  phaser.arriveAndAwaitAdvance(); // 階段1:等待所有線程完成階段1
                  // 執行階段2任務
              }
              phaser.arriveAndDeregister(); // 完成并注銷
          }).start();
      }
      
      // 主線程等待所有線程完成
      phaser.arriveAndAwaitAdvance();
      
      1. 其他,另外還有volatile,這種能保證可見性和有序性,但不能保證原子性的關鍵字。以及基于CAS實現的Atomic 類(無鎖同步),但是僅適用于簡單數據類型和部分操作(如 getAndAdd)。

      死鎖

      死鎖,通常是指在兩個或多個進程(或線程、事務)在執行過程中,因爭奪資源而陷入相互等待的狀態,導致所有進程都無法繼續執行。

      什么情況下會產生死鎖?

      產生死鎖的四個必要條件

      • 互斥(Mutual Exclusion),一個資源只能被一個進程占用,其他進程必須等待其釋放。
      • 占有并等待(Hold and Wait),進程在持有資源的同時,申請新的資源。
      • 不可剝奪(No Preemption),資源只能由持有它的進程主動釋放,不能被強制剝奪。
      • 循環等待(Circular Wait),存在一個進程環,每個進程都在等待下一個進程所持有的資源。

      image

      如何解決死鎖?

      上面我們已經知道產生死鎖有四個必要條件,那解決死鎖,只需要破壞死鎖的這些必要條件即可。
      一般從以下幾方面入手即可:

      • 破壞“占有并等待”條件

        1. 進程或線程一次性申請所需的所有資源,否則不分配任何資源。(可能導致資源利用率低,進程長期等待資源
        2. 進程或線程申請資源時,必須釋放已持有的所有資源。(可能導致頻繁的資源釋放和重新申請,增加系統開銷
      • 破壞“不可剝奪”條件,允許系統強制回收資源。(可能中斷進程的正常執行,導致數據不一致

      • 破壞“循環等待”條件,要求進程或線程按順序申請資源。保證多個進程(線程)的執行順序相同即可避免循環等待。這是最常用的解決死鎖的方法。

        例如:事務1的執行順序是:A->B->C,事務2的執行順序是:C->D->A,這種情況下就容易產生死鎖。因為事務1占用了A,等待C,但是事務2占用了C但是等待A。因此只需要把事務2的執行順序改成:A->D->C,這樣事務2在執行時,會發現事務1占用著A呢,因此事務會先不執行,等待事務1釋放A。
        image

      死鎖如何恢復?

      • 回滾進程或線程,可以執行一個或多個進程(或線程)回滾到安全狀態,釋放資源。一般回滾時,要遵循按優先級選擇(優先級低的進程先回滾)按資源占用時間選擇(占用時間短的進程先回滾)。
      • 終止進程或線程,直接終止全部或部分死鎖進程(或線程),釋放資源。(可能導致數據丟失或事務不完整)
      • 資源剝奪,從某些進程或線程中強制回收資源分配給其他進程。
      • 超時機制,為進程或線程設置等待資源的超時時間,若超時則自動放棄請求并釋放已占資源。

      數據庫中的死鎖

      在操作數據庫時,如果有多個事務并發執行,也是可能發生死鎖的。當事務1持有資源A的鎖,但是嘗試獲取資源B的鎖,而事務2持有資源B的鎖,嘗試獲取資源A的鎖的時候,這時候就會發生死鎖的情況。

      當數據庫發生死鎖的時候,會報出來如下的錯誤:

      Error updating database. Cause: ERR-CODE: [TDDL-4614][ERR EXECUTE ON MYSQL]
      Deadlock found when trying to get lock;
      
      The error occurred while setting parameters### SQL:
      
      update test_table set updated=now(),type_state = ? where test_num = 123
      
      

      數據庫操作中如何避免死鎖?

      一般對于數據庫的死鎖,主要是避免發生并發更新同一資源的操作。或者可以考慮保證操作的順序,比如多個事務都是先操作資源A、再操作資源B,這樣就能有效的避免死鎖。

      還有一些其他優化措施:
      減少事務持有鎖的時間:盡快提交或回滾事務。
      鎖粒度控制:使用行級鎖而非表級鎖,減少資源競爭。
      避免嵌套事務:減少循環等待的可能性。

      多線程編排

      在 Java 中,多線程的編排可以通過多種方式實現,主要涉及 線程池同步機制并發工具類 以及 任務協調工具(如 FutureCompletableFuture)等。

      CompletableFuture怎么實現多線程異步編排?

      CompletableFuture,提供了非常強大的Future的擴展功能,可以幫助我們簡化異步編程的復雜性,提供了函數式編程的能力,可以通過回調的方式處理計算結果,并且提供了轉換和組合CompletableFuture的方法。
      我在【上一篇文章】提過CompletableFuture底層就是用ForkJoinPool來實現,那么CompletableFuture如何使用來實現多線程任務編排的呢?

      單個任務
      runAsync:無返回值
      CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
          System.out.println("無返回值任務執行中");
      });
      
      supplyAsync:有返回值
      CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
          return "異步任務結果";
      });
      System.out.println(future.get()); // 輸出: 異步任務結果
      
      指定線程池

      因為CompletableFuture默認底層是使用的ForkJoinPool.commonPool(),但是也是可以自定義線程池,配置線程的一些指定信息。

      ExecutorService executor = Executors.newFixedThreadPool(2);
      CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
          return "自定義線程池任務";
      }, executor);
      
      兩個任務編排

      thenApplyAsync:能接收上一次的執行結果,還可以有返回值

      CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello")
          .thenApplyAsync(result -> result + " World");// 運行結果 Hello World
      

      thenRunAsync:不能接收上一次的執行結果,并且也沒返回值

      CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
                  return "Hello";
              }).thenRunAsync(() -> {
                  System.out.println("after Hello World");
              });
      
      組合多個任務編排
      1. 串行組合(thenCompose,可以將前一個任務的結果傳遞給下一個任務(鏈式依賴)
      CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello")
      .thenCompose(result -> CompletableFuture.supplyAsync(() -> result + " World"));
      System.out.println(future.get()); // 輸出: Hello World
      
      1. 并行組合(thenCombine),將兩個獨立任務的結果進行合并
      CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> "Hello");
      CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> "World");
      future1.thenCombine(future2, (result1, result2) -> result1 + " " + result2)
             .thenAccept(System.out::println); // 輸出: Hello World
      
      1. 多任務并行(allOf / anyOf)
      • allOf:等待所有任務完成
      CompletableFuture<Void> allFutures = CompletableFuture.allOf(
          CompletableFuture.runAsync(() -> System.out.println("Task 1")),
          CompletableFuture.runAsync(() -> System.out.println("Task 2"))
      );
      allFutures.get(); // 等待所有任務完成
      
      • anyOf:任一任務完成即觸發
      CompletableFuture<Object> anyFuture = CompletableFuture.anyOf(
          CompletableFuture.supplyAsync(() -> "Task 1"),
          CompletableFuture.supplyAsync(() -> "Task 2")
      );
      System.out.println(anyFuture.get()); // 輸出: Task 1 或 Task 2(取決于哪個先完成)
      
      任務編排異常處理
      1. 捕獲異常(exceptionally,在任務拋出異常時提供默認信息。
      CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
          if (Math.random() > 0.5) throw new RuntimeException("失敗");
          return "成功";
      }).exceptionally(ex -> {
          System.out.println("異常處理: " + ex.getMessage());
          return "默認值";
      });
      System.out.println(future.get());
      
      1. 全局處理(handle / whenComplete
      • handle:處理異常并返回新結果
      CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
          if (Math.random() > 0.5) throw new RuntimeException("失敗");
          return "成功";
      }).handle((result, ex) -> {
          if (ex != null) {
              System.out.println("異常處理: " + ex.getMessage());
              return "默認值";
          }
          return result;
      });
      
      • whenComplete:無論成功或失敗均執行(不可中斷)
      CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
          if (Math.random() > 0.5) throw new RuntimeException("失敗");
          return "成功";
      }).whenComplete((result, ex) -> {
          if (ex != null) System.out.println("任務失敗");
          else System.out.println("任務成功: " + result);
      });
      
      posted @ 2025-09-10 10:40  紀莫  閱讀(647)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲精品自拍在线视频| 精品国产AⅤ无码一区二区| 欧美视频精品免费覌看| 亚洲综合激情五月色一区| 亚洲第一精品一二三区| 久久亚洲国产精品久久| 亚洲熟女一区二区av| 第一精品福利导福航| 男女爽爽无遮挡午夜视频| 丝袜美腿亚洲综合第一页| 亚洲精品国产自在久久| 日韩无专区精品中文字幕| 乱码午夜-极品国产内射| 国产精品久久久久久福利| 免费无码又爽又刺激高潮虎虎视频 | 免费福利视频一区二区三区高清| 国产精品性色一区二区三区| 欧美成人精品手机在线| 亚洲综合精品第一页| 少妇av一区二区三区无码| 特级做a爰片毛片免费看无码| 欧美人与动牲猛交A欧美精品| 国产精品中文字幕观看| 国产做a爱片久久毛片a片| 日本一区二区三区专线| 欧美精品一区二区三区中文字幕| 综合亚洲网| 亚洲成人精品综合在线| 国产精品国产精品国产精品| 亚洲欧美日本久久网站| 精品亚洲综合一区二区三区| 国产一二三五区不在卡| 国产精品免费中文字幕| 亚洲欧洲美洲在线观看| 国产女人喷潮视频免费| 国产精品天干天干综合网 | 国产成人精品亚洲资源| 一本无码人妻在中文字幕免费| 久久精品熟女亚洲av麻| 一卡二卡三卡四卡视频区| 国产精品亚洲一区二区三区|