CyclicBarrier 基本用法

CyclicBarrier 基本用法

簡介

CyclicBarrier 是 Java 并發包(java.util.concurrent)中的一個同步輔助類。它允許一組線程相互等待,直到到達某個公共屏障點(common barrier point)。只有當所有參與的線程都到達屏障點時,這些線程才能繼續執行。這與CountDownLatch不同,后者是一次性的,而CyclicBarrier可以在等待的線程被釋放后重新使用。

使用場景

多線程任務中,讓多個線程在某個特定的點上同步,確保完成所有線程都完成某個階段后,再一起進入下一階段。

比如:一個計算任務被分成了多個部分,每個部分由不同的線程進行處理,處理完成后需要匯總結果,這時候需要所有線程都完成計算后,才能進行匯總。

基本用法

創建 CyclicBarrier

使用 new CyclicBarrier(int parties) 創建一個新的 CyclicBarrier,其中 parties 參數指定了必須調用 await() 方法以使所有線程都能通過屏障的線程數量。

也可以提供第二個參數,這是一個 Runnable,當最后一個線程到達屏障時會執行這個Runnable,這可以用于在所有線程到達屏障之前執行一些特定的操作。

線程中使用 await() 方法

每個線程在需要等待其他線程的地方調用 await() 方法。該方法會掛起當前線程,直到所有線程都調用了 await() 方法。

如果當前線程不是最后一個到達屏障的線程,await() 將阻塞直到所有線程都到達。如果當前線程是最后一個到達的,則所有線程都會被喚醒繼續執行。

重置屏障

可以通過調用 reset() 方法來重置 CyclicBarrier,這將導致所有等待的線程收到一個 BrokenBarrierException 異常,并且屏障計數會被重置為其初始狀態。

示例

說明:

使用休眠函數模擬實際業務執行的耗時,使用線程池多線程的執行任務,所有任務完成后,匯總計算結果。

公共代碼

給出模擬函數,以及線程池定義等前置條件代碼。

package com.ysx.utils.concurrent;import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.security.SecureRandom;
import java.util.Map;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;public class CyclicBarrierTest {private static final Logger LOGGER = LoggerFactory.getLogger(CyclicBarrierTest.class);// 使用map模擬所有的數據,每個線程占據一個keyprivate final Map<Integer, Integer> countMap = new ConcurrentHashMap<>();// 核心線程數private static final int CORE_POOL_SIZE = 5;// 線程池private static final ExecutorService THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, CORE_POOL_SIZE * 2,10, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1000));/*** 使用一個休眠函數,模擬實際業務的計算,并且等待其他線程的結束** @param cyclicBarrier 屏障獨顯* @param index 數據的key,這里用index表示*/private void calculate(CyclicBarrier cyclicBarrier, int index) {SecureRandom secureRandom = new SecureRandom();// 隨機休眠時間,并作為數據值int randomSleepSeconds = secureRandom.nextInt(10);LOGGER.info("<{}> index: {}, randomSleepSeconds: {}.", Thread.currentThread().getName(), index, randomSleepSeconds);// 休眠,模擬線程計算耗時try {Thread.sleep(randomSleepSeconds * 1000);} catch (InterruptedException e) {throw new RuntimeException(e);}// 記錄計算結果countMap.put(index, randomSleepSeconds);// 等待其他線程到達這個點LOGGER.info("<{}> index: {}, waiting other thread.", Thread.currentThread().getName(), index);try {cyclicBarrier.await();} catch (InterruptedException e) {throw new RuntimeException(e);} catch (BrokenBarrierException e) {throw new RuntimeException(e);}// 通過了這個屏障LOGGER.info("<{}> index: {}, has passed barrier.", Thread.currentThread().getName(), index);}}

場景1 基本用法

任務數量不超過線程池的核心線程數

@Test
@DisplayName("基本用法:任務數量不超過線程池的核心線程數")
public void test1() {int taskNum = 3;int threadNum = Math.min(CORE_POOL_SIZE, taskNum);// 這里 CyclicBarrier 的構造函數的參數 parties 表示需要攔截的線程的數量,示例中有3個子線程,1個主線程CyclicBarrier cyclicBarrier = new CyclicBarrier(threadNum + 1);for (int i = 0; i < threadNum; i++) {final int index = i;THREAD_POOL_EXECUTOR.execute(() -> calculate(cyclicBarrier, index));}try {// 等待所有子線程任務執行完成,超時時間為1分鐘LOGGER.info("waiting all thread.");cyclicBarrier.await(1, TimeUnit.MINUTES);LOGGER.info("<{}> has passed barrier.", Thread.currentThread().getName());} catch (InterruptedException e) {throw new RuntimeException(e);} catch (BrokenBarrierException e) {throw new RuntimeException(e);} catch (TimeoutException e) {throw new RuntimeException(e);}LOGGER.info("finish calculate.");int sum = countMap.values().stream().mapToInt(Integer::intValue).sum();LOGGER.info("sum: {}.", sum);
}

運行后日志打印參考:(日志打印忽略時間戳)

[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:105 - waiting all thread.
[pool-2-thread-3]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-3> index: 2, randomSleepSeconds: 7.
[pool-2-thread-1]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-1> index: 0, randomSleepSeconds: 7.
[pool-2-thread-2]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-2> index: 1, randomSleepSeconds: 7.
[pool-2-thread-2]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-2> index: 1, waiting other thread.
[pool-2-thread-3]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-3> index: 2, waiting other thread.
[pool-2-thread-1]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-1> index: 0, waiting other thread.
[pool-2-thread-3]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-3> index: 2, has passed barrier.
[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:108 - <main> has passed barrier.
[pool-2-thread-1]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-1> index: 0, has passed barrier.
[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:116 - finish calculate.
[pool-2-thread-2]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-2> index: 1, has passed barrier.
[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:118 - sum: 21.

日志說明:

  • 有3個任務,分別用3個子線程執行,主線程調用 cyclicBarrier.await(1, TimeUnit.MINUTES);方法,表示等待子線程任務執行完成,之后匯總結果。

場景2 構造函數中指定Runnable

構造函數Runnable的用法:該Runnable優先級高

@Test
@DisplayName("構造函數Runnable的用法:該Runnable優先級高")
public void test2() {int taskNum = 3;int threadNum = Math.min(CORE_POOL_SIZE, taskNum);// 這里 CyclicBarrier 的構造函數的參數 parties 表示需要攔截的線程的數量,示例中有3個子線程,1個主線程CyclicBarrier cyclicBarrier = new CyclicBarrier(threadNum + 1, new Runnable() {@Overridepublic void run() {LOGGER.info("<{}> is first priority.", Thread.currentThread().getName());}});for (int i = 0; i < threadNum; i++) {final int index = i;THREAD_POOL_EXECUTOR.execute(() -> calculate(cyclicBarrier, index));}try {// 等待所有子線程任務執行完成,超時時間為1分鐘LOGGER.info("waiting all thread.");cyclicBarrier.await(1, TimeUnit.MINUTES);LOGGER.info("<{}> has passed barrier.", Thread.currentThread().getName());} catch (InterruptedException e) {throw new RuntimeException(e);} catch (BrokenBarrierException e) {throw new RuntimeException(e);} catch (TimeoutException e) {throw new RuntimeException(e);}LOGGER.info("finish calculate.");int sum = countMap.values().stream().mapToInt(Integer::intValue).sum();LOGGER.info("sum: {}.", sum);
}

打印日志參考:

[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:139 - waiting all thread.
[pool-2-thread-3]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-3> index: 2, randomSleepSeconds: 9.
[pool-2-thread-2]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-2> index: 1, randomSleepSeconds: 7.
[pool-2-thread-1]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-1> index: 0, randomSleepSeconds: 6.
[pool-2-thread-1]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-1> index: 0, waiting other thread.
[pool-2-thread-2]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-2> index: 1, waiting other thread.
[pool-2-thread-3]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-3> index: 2, waiting other thread.
[pool-2-thread-3]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:130 - <pool-2-thread-3> is first priority.
[pool-2-thread-1]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-1> index: 0, has passed barrier.
[pool-2-thread-2]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-2> index: 1, has passed barrier.
[pool-2-thread-3]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-3> index: 2, has passed barrier.
[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:142 - <main> has passed barrier.
[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:150 - finish calculate.
[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:152 - sum: 22.

日志說明:

  • 即構造函數的Runnable的優先級最高,在其他所有到達屏障點之后,這個線程的代碼最先執行。

場景3 通用場景:分批處理

使用線程池處理的場景,由于線程池數量是有限的,所以一次并發執行的線程數是有上限的,比如為5,當總任務數為13時,就需要把任務分批處理,以線程池核心線程數量分批,13個任務和分為3批,每個批次分別為5,5,3個任務。在所有批次執行完成之后,再匯總所有的數據。

分批場景需要考慮最后一批的執行,最后一批的數量可能存在小于核心線程數量的情況,要以實際的數量為準。

參考代碼如下:

@Test
@DisplayName("通用用法:任務數量存在超過線程池的核心線程數的場景,需要分批處理")
public void test3() {int taskNum = 13;// 計算分批計算的批次:任務數/核心線程數,并向上取整int batchNum = (int) Math.ceil((double) taskNum / CORE_POOL_SIZE);for (int batchIndex = 0; batchIndex < batchNum; batchIndex++) {int threadNum = CORE_POOL_SIZE;if (batchIndex == batchNum - 1) {// 如果是最后一批,需要以實際剩余的任務數作為線程數threadNum = taskNum - batchIndex * CORE_POOL_SIZE;}LOGGER.info("batch calculate, batchIndex: {}, threadNum: {}.", batchIndex, threadNum);// 這里 CyclicBarrier 的構造函數的參數 parties 表示需要攔截的線程的數量,這里有threadNum個子線程,1個主線程CyclicBarrier cyclicBarrier = new CyclicBarrier(threadNum + 1);for (int threadIndex = 0; threadIndex < threadNum; threadIndex++) {// 當前數據的index需要單獨計數final int index = threadIndex + batchIndex * CORE_POOL_SIZE;THREAD_POOL_EXECUTOR.execute(() -> calculate(cyclicBarrier, index));}try {// 當前批次,等待所有子線程任務執行完成,超時時間為1分鐘LOGGER.info("waiting all thread in this batch, batchIndex: {}.", batchIndex);cyclicBarrier.await(1, TimeUnit.MINUTES);LOGGER.info("<{}> has passed barrier in this batch, batchIndex: {}.", Thread.currentThread().getName(), batchIndex);} catch (InterruptedException e) {throw new RuntimeException(e);} catch (BrokenBarrierException e) {throw new RuntimeException(e);} catch (TimeoutException e) {throw new RuntimeException(e);}}LOGGER.info("finish calculate.");int sum = countMap.values().stream().mapToInt(Integer::intValue).sum();LOGGER.info("sum: {}.", sum);
}

參考日志:

[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:168 - batch calculate, batchIndex: 0, threadNum: 5.
[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:178 - waiting all thread in this batch, batchIndex: 0.
[pool-2-thread-1]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-1> index: 0, randomSleepSeconds: 3.
[pool-2-thread-3]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-3> index: 2, randomSleepSeconds: 8.
[pool-2-thread-5]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-5> index: 4, randomSleepSeconds: 8.
[pool-2-thread-4]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-4> index: 3, randomSleepSeconds: 8.
[pool-2-thread-2]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-2> index: 1, randomSleepSeconds: 7.
[pool-2-thread-1]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-1> index: 0, waiting other thread.
[pool-2-thread-2]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-2> index: 1, waiting other thread.
[pool-2-thread-3]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-3> index: 2, waiting other thread.
[pool-2-thread-5]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-5> index: 4, waiting other thread.
[pool-2-thread-4]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-4> index: 3, waiting other thread.
[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:181 - <main> has passed barrier in this batch, batchIndex: 0.
[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:168 - batch calculate, batchIndex: 1, threadNum: 5.
[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:178 - waiting all thread in this batch, batchIndex: 1.
[pool-2-thread-1]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-1> index: 0, has passed barrier.
[pool-2-thread-1]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-1> index: 5, randomSleepSeconds: 8.
[pool-2-thread-2]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-2> index: 1, has passed barrier.
[pool-2-thread-3]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-3> index: 2, has passed barrier.
[pool-2-thread-3]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-3> index: 7, randomSleepSeconds: 8.
[pool-2-thread-2]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-2> index: 6, randomSleepSeconds: 8.
[pool-2-thread-5]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-5> index: 4, has passed barrier.
[pool-2-thread-5]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-5> index: 8, randomSleepSeconds: 5.
[pool-2-thread-4]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-4> index: 3, has passed barrier.
[pool-2-thread-4]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-4> index: 9, randomSleepSeconds: 3.
[pool-2-thread-4]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-4> index: 9, waiting other thread.
[pool-2-thread-5]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-5> index: 8, waiting other thread.
[pool-2-thread-2]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-2> index: 6, waiting other thread.
[pool-2-thread-3]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-3> index: 7, waiting other thread.
[pool-2-thread-1]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-1> index: 5, waiting other thread.
[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:181 - <main> has passed barrier in this batch, batchIndex: 1.
[pool-2-thread-4]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-4> index: 9, has passed barrier.
[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:168 - batch calculate, batchIndex: 2, threadNum: 3.
[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:178 - waiting all thread in this batch, batchIndex: 2.
[pool-2-thread-5]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-5> index: 8, has passed barrier.
[pool-2-thread-5]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-5> index: 10, randomSleepSeconds: 2.
[pool-2-thread-3]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-3> index: 7, has passed barrier.
[pool-2-thread-2]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-2> index: 6, has passed barrier.
[pool-2-thread-3]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-3> index: 12, randomSleepSeconds: 5.
[pool-2-thread-4]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:67 - <pool-2-thread-4> index: 11, randomSleepSeconds: 9.
[pool-2-thread-1]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-1> index: 5, has passed barrier.
[pool-2-thread-5]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-5> index: 10, waiting other thread.
[pool-2-thread-3]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-3> index: 12, waiting other thread.
[pool-2-thread-4]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:79 - <pool-2-thread-4> index: 11, waiting other thread.
[pool-2-thread-5]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-5> index: 10, has passed barrier.
[pool-2-thread-3]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-3> index: 12, has passed barrier.
[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:181 - <main> has passed barrier in this batch, batchIndex: 2.
[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:191 - finish calculate.
[pool-2-thread-4]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:88 - <pool-2-thread-4> index: 11, has passed barrier.
[main]  INFO  com.ysx.utils.concurrent.CyclicBarrierTest:193 - sum: 82.

日志說明:

  • 分批處理,每個批次內部是并發執行的。
  • 在所有批次執行完成之后,再匯總計算結果。

源代碼地址

  • github
  • gitee

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/76711.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/76711.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/76711.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[特殊字符] 手機連接車機熱點并使用 `iperf3` 測試網絡性能

好的&#xff0c;以下是根據你的描述整理出來的步驟及解釋&#xff1a; &#x1f4f6; 手機連接車機熱點并使用 iperf3 測試網絡性能 本文將通過 iperf3 來測試手機和車機之間的網絡連接性能。我們會讓車機作為服務端&#xff0c;手機作為客戶端&#xff0c;進行 UDP 流量傳輸…

FPGA上實現SD卡連續多塊讀的命令

在FPGA上實現SD卡連續多塊讀的命令 CMD17命令一次只能讀取1個塊 CMD18命令一次可以連續讀取多個塊&#xff0c;直到停止命令CMD12 CMD18命令讀的塊數程序可任意設置 目錄 前言 一、SD卡多塊讀命令CMD18 二、停止讀命令CMD12 三、SD卡初始化SD卡連續塊讀操作的verilog代碼 …

DeepSeek 助力 Vue3 開發:打造絲滑的日歷(Calendar)

前言&#xff1a;哈嘍&#xff0c;大家好&#xff0c;今天給大家分享一篇文章&#xff01;并提供具體代碼幫助大家深入理解&#xff0c;徹底掌握&#xff01;創作不易&#xff0c;如果能幫助到大家或者給大家一些靈感和啟發&#xff0c;歡迎收藏關注哦 &#x1f495; 目錄 Deep…

NSGA-II 多目標優化 —— 理論、案例與交互式 GUI 實現

目錄 NSGA-II 多目標優化 —— 理論、案例與交互式 GUI 實現一、引言二、NSGA-II 基本原理2.1 非支配排序2.2 擁擠距離2.3 算法流程三、數學模型與算法推導3.1 多目標優化問題描述3.2 非支配關系與排序3.3 擁擠距離計算四、NSGA-II 的優缺點4.1 優點4.2 缺點五、典型案例分析5.…

庫學習04——numpy

一、基本屬性 二、 創建數組 &#xff08;一&#xff09;arange a np.arange(10,20,2) # [10,12,14,16,18] 只有一個參數n的話&#xff0c;默認是從0到n-1的一維數組。 &#xff08;二&#xff09;自定義reshape a np.arange(12).reshape((3,4)) [[ 0 1 2 3][ 4 5 …

NVIDIA Jetson 快速切換CUDA版本| 多CUDA版本

當NVIDIA Jetson中安裝了多個CUDA時&#xff0c;可以通過命令&#xff0c;快速切換不同版本的。 這樣在環境變量和代碼編譯時&#xff0c;能使用指定版本的CUDA了。 本文適用于Jetson Nano、TX1/TX2、Xavier 和 Orin系列的設備&#xff0c;供大家參考。 cuda參考地址&#xf…

當開源邂逅AI,公益長出翅膀 | 回顧3.30 上海「開源×AI 賦能公益」Meetup

在春和景明的三月&#xff0c;一場打破常規的公益聚會在上海剪愛公益發展中心肇清項目點溫暖上演。這&#xff0c;便是G-Star公益行帶來的「開源AI 賦能公益」Meetup&#xff0c;一場技術與善意交織、創新與溫暖共生的奇妙之旅。 活動現場&#xff0c;沒有高冷的技術壁壘&#…

高階函數/柯里化/純函數

本篇文章主要是介紹一下標題里面的概念&#xff0c;在面試的時候經常文檔&#xff0c;結合閱讀到的資料&#xff0c;結合本人的個人見解出品了該文章&#xff0c;如有寫的不好的地方或理解有誤的&#xff0c;還望閣下多多指教。 1、高階函數 什么是高階函數&#xff1f; 接受…

Docker+Jenkins+Gitee自動化項目部署

前置條件 docker安裝成功 按照下面配置加速 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-EOF {"registry-mirrors": ["https://register.librax.org"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker一、…

穿梭在數字王國:Python進制轉換奇遇記

穿梭在數字王國:Python進制轉換奇遇記 想象一下,你是一位勇敢的探險家,正在穿越神秘的"數字王國"。在這個王國里,不同的地區使用著不同的語言(或者說,進制)。二進制村的居民只懂"0"和"1";八進制鎮的人們使用0到7的數字;而十六進制城的…

FileInputStream 詳解與記憶方法

FileInputStream 詳解與記憶方法 一、FileInputStream 核心概念 FileInputStream 是 Java 中用于從文件讀取原始字節的類&#xff0c;繼承自 InputStream 抽象類。 1. 核心特點 特性說明繼承關系InputStream → FileInputStream數據單位字節&#xff08;8bit&#xff09;用…

設計模式 四、行為設計模式(2)

五、狀態模式 1、概述 狀態設計模式是一種行為型設計模式&#xff0c;它允許對象在其內部狀態發生時改變其行為&#xff0c;這種模式可以消除大量的條件語句&#xff0c;并將每個狀態的行為封裝到單獨的類中。 狀態模式的主要組成部分如下&#xff1a; 1&#xff09;上…

大模型學習八:?Sealos 私有化部署之VMware 安裝ubuntu22.04 虛擬機安裝(實操)

一、說明 windows 11 ubuntu22.04.5 安裝5個虛擬機&#xff0c;3個master 2個node 二、安裝 Vmware 17&#xff08;沒成功&#xff0c;但你可以成功&#xff09; 我的電腦配置比較舊&#xff0c;直接提示處理器不支持xsave 無法打開虛擬機的電源&#xff0c;網上方法試過了…

Win32++ 使用初探

文章目錄 1. 環境要求2. Win32安裝3. 項目創建3.1 項目創建&#xff08;1&#xff09;直接使用Win32里的示例Sample&#xff08;2&#xff09;自行創建項目 最近想用 VC寫些 UI&#xff0c;但又不太想用 MFC&#xff0c;正好對界面要求不太高&#xff0c;就使用了一下 Win3…

R 語言科研繪圖第 38 期 --- 餅狀圖-玫瑰

在發表科研論文的過程中&#xff0c;科研繪圖是必不可少的&#xff0c;一張好看的圖形會是文章很大的加分項。 為了便于使用&#xff0c;本系列文章介紹的所有繪圖都已收錄到了 sciRplot 項目中&#xff0c;獲取方式&#xff1a; R 語言科研繪圖模板 --- sciRplothttps://mp.…

Linux驅動開發進階(六)- 多線程與并發

文章目錄 1、前言2、進程與線程3、內核線程4、底半步機制4.1、軟中斷4.2、tasklet4.3、工作隊列4.3.1、普通工作項4.3.2、延時工作項4.3.3、工作隊列 5、中斷線程化6、進程6.1、內核進程6.2、用戶空間進程 7、鎖機制7.1、原子操作7.2、自旋鎖7.3、信號量7.4、互斥鎖7.5、comple…

第四節:React Hooks進階篇-useEffect依賴項為空數組[]與不寫的區別

陷阱題&#xff1a;閉包問題、Stale Closure舉例 一、依賴項為空數組[]與不寫的核心區別 行為空數組[]不寫依賴項執行時機僅在組件掛載時執行一次&#xff08;類似componentDidMount&#xff09;組件每次渲染后都執行&#xff08;類似componentDidUpdate&#xff09;更新觸發…

【第39節】windows編程:打造MFC版本任務管理器

目錄 一、項目概述 二、項目開發的各種功能關鍵 2.1 進程信息的獲取 2.2 線程信息的獲取 2.3 進程模塊信息的獲取 2.3.1 模塊快照 2.3.2 枚舉模塊 2.4 進程堆信息的獲取 2.5 窗口信息的獲取 2.6 文件信息的獲取 2.7 內存信息和CPU占用率的獲取 2.7.1 內存信息相關結…

計算軸承|滾動軸承故障頻率

一、軸承故障頻率概述 在旋轉機械故障診斷中&#xff0c;軸承故障頻率&#xff08;BPFO、BPFI、BSF、FTF&#xff09;是重要的分析依據。通過計算這些特征頻率&#xff0c;可以幫助工程師&#xff1a; 識別軸承故障類型&#xff08;內圈/外圈/滾動體故障&#xff09;制定振動…

【數據結構與算法】ArrayList 和 順序表

文章目錄 &#x1f332;List&#x1f332;1. 線性表&#x1f332;2. 順序表&#x1f33f;2.1 MyArrayList2.1.1 類中重寫所有接口方法1.新增元素2.在pos位置新增元素(指定位置)3.判定是否包含了某個特定元素 4.查找特定元素對應的位置 5.獲取pos下標的元素 6.給pos位置的元素替…