回顧JAVA中的鎖機制

Java中的鎖機制

在Java中,鎖機制是多線程編程里保障數據一致性與線程安全的關鍵技術。

1. 內置鎖:synchronized關鍵字

synchronized是Java的內置鎖機制,能夠保證在同一時刻,只有一個線程可以執行被其修飾的代碼塊或方法。

用法示例
public class SynchronizedExample {private int count = 0;// 同步方法public synchronized void increment() {count++;}// 同步代碼塊public void decrement() {synchronized(this) {count--;}}
}
實現原理

synchronized是基于對象頭中的Mark Word來實現的。當一個線程訪問同步代碼塊時,會先查看對象的Mark Word。如果Mark Word顯示該對象沒有被鎖定,那么這個線程就會將Mark Word設置為鎖定狀態,然后開始執行同步代碼塊。在這個線程執行同步代碼塊期間,如果其他線程也想訪問這個同步代碼塊,它們會發現對象的Mark Word已經被設置為鎖定狀態,于是這些線程就會被阻塞,進入等待隊列。

2. 顯示鎖:Lock接口

Lock接口是Java 5引入的,它提供了比synchronized更靈活、更強大的鎖控制能力。

核心方法
  • lock():獲取鎖,如果鎖不可用,則線程會被阻塞。
  • unlock():釋放鎖,必須在finally塊中調用,以確保鎖一定會被釋放。
  • tryLock():嘗試獲取鎖,如果鎖可用,則獲取鎖并返回true;如果鎖不可用,則立即返回false,不會阻塞線程。
用法示例
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class LockExample {private final Lock lock = new ReentrantLock();private int count = 0;public void increment() {lock.lock();try {count++;} finally {lock.unlock();}}
}

3. ReentrantLock(可重入鎖)

ReentrantLockLock接口的一個重要實現類,它支持可重入鎖的特性。所謂可重入鎖,就是指同一個線程可以多次獲取同一把鎖,而不會出現死鎖的情況。

特性
  • 公平性ReentrantLock可以設置為公平鎖或非公平鎖。公平鎖會按照線程請求鎖的順序來分配鎖,而非公平鎖則不保證這一點,有可能后請求的線程先獲得鎖。
  • 可重入性:同一個線程可以多次獲取同一把鎖,每獲取一次,鎖的計數器就會加1,每釋放一次,鎖的計數器就會減1,當計數器為0時,鎖才會被真正釋放。
公平鎖示例
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class FairLockExample {private final Lock fairLock = new ReentrantLock(true); // true表示公平鎖public void performTask() {fairLock.lock();try {// 執行任務} finally {fairLock.unlock();}}
}

4. ReentrantReadWriteLock(讀寫鎖)

ReentrantReadWriteLock提供了讀寫分離的鎖機制,它維護了一對鎖,一個讀鎖和一個寫鎖。

特性
  • 讀鎖:允許多個線程同時獲取讀鎖,用于并發讀取共享資源。
  • 寫鎖:寫鎖是排他鎖,同一時刻只允許一個線程獲取寫鎖,用于修改共享資源。
  • 讀寫互斥:讀鎖和寫鎖不能同時被獲取,即當有線程獲取了讀鎖時,其他線程不能獲取寫鎖;當有線程獲取了寫鎖時,其他線程不能獲取讀鎖和寫鎖。
用法示例
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;public class Cache {private final ReadWriteLock rwLock = new ReentrantReadWriteLock();private Object data;public Object read() {rwLock.readLock().lock();try {return data;} finally {rwLock.readLock().unlock();}}public void write(Object newData) {rwLock.writeLock().lock();try {data = newData;} finally {rwLock.writeLock().unlock();}}
}

5. StampedLock(郵戳鎖)

StampedLock是Java 8引入的一種新的鎖機制,它提供了比ReentrantReadWriteLock更細粒度的鎖控制。可以有效應對A-B-A問題。

特性
  • 樂觀讀鎖:樂觀讀鎖是一種無鎖機制,它允許在沒有獲取鎖的情況下讀取共享資源。讀取完成后,需要驗證資源是否在讀取期間被修改過,如果沒有被修改過,則讀取有效;如果被修改過,則需要重新讀取。
  • 悲觀讀鎖和寫鎖:與ReentrantReadWriteLock的讀鎖和寫鎖類似,但StampedLock的悲觀讀鎖和寫鎖是通過返回一個郵戳(stamp)來控制的。
用法示例
import java.util.concurrent.locks.StampedLock;public class Point {private double x, y;private final StampedLock sl = new StampedLock();public double distanceFromOrigin() {long stamp = sl.tryOptimisticRead(); // 嘗試樂觀讀double currentX = x, currentY = y;if (!sl.validate(stamp)) { // 驗證是否有寫操作發生stamp = sl.readLock(); // 獲取悲觀讀鎖try {currentX = x;currentY = y;} finally {sl.unlockRead(stamp);}}return Math.sqrt(currentX * currentX + currentY * currentY);}
}

6. 鎖的優化

鎖粗化(Lock Coarsening)

鎖粗化是指將多次連續的加鎖和解鎖操作合并為一次加鎖和解鎖操作,以減少鎖的獲取和釋放帶來的性能開銷。

鎖消除(Lock Elimination)

鎖消除是指在編譯時,Java編譯器會對一些代碼進行分析,如果發現某些鎖是不必要的,就會將這些鎖消除掉,從而提高代碼的執行效率。

偏向鎖(Biased Locking)

偏向鎖是一種針對單線程環境的鎖優化機制。當一個線程第一次獲取鎖時,鎖會被標記為偏向鎖,并記錄該線程的ID。當該線程再次獲取鎖時,無需進行任何同步操作,直接獲取鎖,從而提高了單線程環境下的性能。

輕量級鎖(Lightweight Locking)

輕量級鎖是一種在多線程環境下,但線程競爭不激烈時的鎖優化機制。當線程競爭不激烈時,輕量級鎖可以避免線程的阻塞和喚醒操作,從而提高了性能。

自旋鎖(Spin Lock)

自旋鎖是指當一個線程獲取鎖失敗時,它不會立即被阻塞,而是會在原地循環等待,直到鎖被釋放。自旋鎖適用于鎖的持有時間較短的場景,可以減少線程的阻塞和喚醒帶來的性能開銷。

7. 選擇合適的鎖

  • synchronized:適用于簡單的同步場景,代碼簡潔,由JVM自動管理鎖的獲取和釋放。
  • ReentrantLock:適用于需要更靈活的鎖控制的場景,如可中斷鎖、公平鎖等。
  • ReentrantReadWriteLock:適用于讀多寫少的場景,可以提高并發讀取的性能。
  • StampedLock:適用于讀多寫少且讀操作性能要求較高的場景,提供了樂觀讀鎖機制,進一步提高了讀操作的性能。

通過合理使用這些鎖機制,你可以在多線程編程中實現高效且安全的并發控制。

重入鎖和內置鎖的選用

在Java里,重入鎖(ReentrantLock)和內置鎖(synchronized)都可用于實現線程同步,不過它們的適用場景存在差異。下面為你介紹選擇使用重入鎖還是內置鎖的依據:

優先考慮內置鎖的情況

  • 語法簡潔:內置鎖是通過synchronized關鍵字來實現的,無需手動釋放鎖,JVM會自動處理鎖的獲取和釋放,這樣能降低因忘記釋放鎖而導致死鎖的風險。
    public synchronized void method() {// 同步代碼塊
    }
    
  • 對性能要求不高:在JDK 1.6之后,Java對synchronized進行了一系列優化,像偏向鎖、輕量級鎖等,使得它的性能和ReentrantLock相差不大。
  • 鎖的使用場景簡單:若只是需要對方法或代碼塊進行簡單的同步,內置鎖完全可以滿足需求。

優先考慮重入鎖的情況

  • 需要公平鎖:重入鎖可以通過構造函數指定使用公平鎖(new ReentrantLock(true)),公平鎖會按照線程請求鎖的順序來分配鎖,能避免某些線程長時間等待鎖的情況。而內置鎖只能是非公平鎖。
  • 需要靈活的鎖控制:重入鎖提供了一些高級功能,如可中斷鎖、嘗試鎖(tryLock())、帶超時的鎖獲取等。
    Lock lock = new ReentrantLock();
    try {// 嘗試獲取鎖,若鎖被其他線程持有,則當前線程可被中斷lock.lockInterruptibly();// 執行同步操作
    } catch (InterruptedException e) {Thread.currentThread().interrupt();
    } finally {lock.unlock();
    }
    
  • 需要實現條件變量(Condition):重入鎖可以和Condition接口配合使用,實現更靈活的線程等待和喚醒機制,比如實現生產者 - 消費者模式。
    Lock lock = new ReentrantLock();
    Condition condition = lock.newCondition();// 等待條件
    lock.lock();
    try {while (!conditionMet()) {condition.await();}
    } finally {lock.unlock();
    }// 喚醒等待的線程
    lock.lock();
    try {condition.signalAll();
    } finally {lock.unlock();
    }
    

性能方面的考量

  • 低競爭場景:在競爭不激烈的情況下,內置鎖和重入鎖的性能差距不大。
  • 高競爭場景:如果線程之間對鎖的競爭非常激烈,重入鎖的性能可能會略優于內置鎖,因為重入鎖提供了更多的鎖優化選項,例如使用非公平鎖可以減少線程的上下文切換。

總結

  • 推薦優先使用內置鎖:因為它的語法簡潔,由JVM自動管理鎖的獲取和釋放,降低了出錯的概率。
  • 在需要高級特性時使用重入鎖:例如公平鎖、可中斷鎖、條件變量等。

示例對比

內置鎖示例
public class SynchronizedExample {private int count = 0;public synchronized void increment() {count++;}
}
重入鎖示例
import java.util.concurrent.locks.ReentrantLock;public class ReentrantLockExample {private final ReentrantLock lock = new ReentrantLock();private int count = 0;public void increment() {lock.lock();try {count++;} finally {lock.unlock();}}
}

通過對比可以看出,內置鎖的代碼更加簡潔,而重入鎖則提供了更靈活的控制方式。你可以根據具體的需求來選擇合適的鎖機制。

理解各種鎖的特性和適用場景

Java鎖機制中的各類鎖是根據不同場景和需求設計的,理解它們的核心概念、實現方式及適用場景對編寫高效、線程安全的代碼至關重要。以下從分類維度詳細解析常見的鎖類型:

一、按鎖的特性分類

1. 樂觀鎖(Optimistic Locking)
  • 核心思想:假設數據不會被其他線程修改,因此不阻塞訪問,僅在更新時檢查是否有沖突。
  • 實現方式
    • 版本號機制:數據記錄中增加version字段,更新時比較版本號是否一致(如數據庫的UPDATE ... WHERE version = ?);
    • CAS(Compare-And-Swap):Java中通過Unsafe類或Atomic包實現(如AtomicIntegergetAndIncrement())。
  • 使用場景:讀多寫少、沖突概率低的場景(如緩存更新、統計計數)。
  • 示例
    // AtomicInteger基于CAS實現樂觀鎖
    private AtomicInteger counter = new AtomicInteger(0);
    public void increment() {counter.getAndIncrement(); // 內部使用CAS,無需顯式加鎖
    }
    
2. 悲觀鎖(Pessimistic Locking)
  • 核心思想:假設數據隨時會被修改,因此訪問時直接加鎖,阻塞其他線程。
  • 實現方式
    • synchronized關鍵字:Java內置的對象鎖(如synchronized(this));
    • ReentrantLock:可重入鎖,功能更靈活(如支持公平鎖、可中斷鎖)。
  • 使用場景:寫多、沖突概率高的場景(如庫存扣減、銀行轉賬)。
  • 示例
    // synchronized實現悲觀鎖
    public synchronized void transferMoney() {// 操作共享資源
    }
    
3. 自旋鎖(Spin Lock)
  • 核心思想:當鎖被占用時,線程不掛起(不放棄CPU時間片),而是循環嘗試獲取鎖,直到成功。
  • 實現方式
    • 基于CAS實現(如AtomicBooleancompareAndSet());
    • JVM內部的輕量級鎖(偏向鎖膨脹后可能升級為自旋鎖)。
  • 使用場景:鎖持有時間短、線程不希望頻繁掛起/喚醒的場景(如JDK內部的ConcurrentHashMap)。
  • 優點:避免線程上下文切換,提升性能;
  • 缺點:若鎖長時間被占用,會浪費CPU資源。
  • 示例
    // 自定義簡單自旋鎖
    public class SpinLock {private AtomicBoolean locked = new AtomicBoolean(false);public void lock() {while (!locked.compareAndSet(false, true)) {// 循環等待,自旋}}public void unlock() {locked.set(false);}
    }
    

二、按JVM實現分類

4. 偏向鎖(Biased Locking)
  • 核心思想:在單線程環境下,鎖偏向第一個獲取它的線程,后續該線程無需再進行同步操作。
  • 實現方式
    • 對象頭中的Mark Word存儲偏向線程ID;
    • 當有其他線程嘗試競爭鎖時,偏向鎖會被撤銷并升級為輕量級鎖。
  • 使用場景:只有一個線程訪問同步塊的場景(如單例模式的雙重檢查鎖)。
  • 優點:無競爭時幾乎無開銷,提升單線程性能。
5. 輕量級鎖(Lightweight Lock)
  • 核心思想:多線程交替執行同步塊時,通過CAS避免重量級鎖的線程掛起/喚醒操作。
  • 實現方式
    • 線程進入同步塊時,JVM在棧幀中創建鎖記錄(Lock Record);
    • 通過CAS將對象頭的Mark Word指向鎖記錄,成功則獲取鎖,失敗則升級為重量級鎖。
  • 使用場景:線程競爭不激烈,鎖持有時間短的場景。
6. 重量級鎖(Heavyweight Lock)
  • 核心思想:依賴操作系統的互斥量(Mutex)實現,線程競爭鎖失敗時會被掛起(進入內核態)。
  • 實現方式
    • 基于操作系統的pthread_mutex_t(Linux)或CRITICAL_SECTION(Windows);
    • 對象頭的Mark Word指向重量級鎖的指針,鎖競爭時涉及用戶態與內核態的切換。
  • 使用場景:線程競爭激烈,鎖持有時間長的場景。
  • 缺點:性能開銷大,因為涉及內核態與用戶態的切換。

三、按API實現分類

7. 可重入鎖(Reentrant Lock)
  • 核心思想:允許同一個線程多次獲取同一把鎖,而不會被阻塞(通過計數器實現)。
  • 實現方式
    • synchronized關鍵字(隱式可重入);
    • ReentrantLock(顯式可重入,需調用lock()unlock())。
  • 使用場景:方法嵌套調用同步塊的場景(如遞歸函數)。
  • 示例
    // ReentrantLock實現可重入鎖
    private ReentrantLock lock = new ReentrantLock();
    public void outerMethod() {lock.lock();try {innerMethod();} finally {lock.unlock();}
    }public void innerMethod() {lock.lock(); // 同一線程可再次獲取鎖try {// 操作共享資源} finally {lock.unlock();}
    }
    
8. 公平鎖(Fair Lock)
  • 核心思想:鎖的獲取順序按請求時間排序,先到先得(避免線程“饑餓”)。
  • 實現方式
    • ReentrantLock(true):構造函數傳入true啟用公平鎖;
    • 基于FIFO隊列實現,線程競爭鎖時會進入隊列等待。
  • 使用場景:對線程執行順序敏感的場景(如資源分配)。
  • 缺點:公平鎖的性能通常低于非公平鎖,因為需要維護隊列。
9. 讀寫鎖(ReadWrite Lock)
  • 核心思想:將鎖分為讀鎖和寫鎖,允許多個線程同時讀,但寫時互斥。
  • 實現方式
    • ReentrantReadWriteLock:支持讀鎖(共享鎖)和寫鎖(排他鎖);
    • 讀鎖可被多個線程同時持有,寫鎖只能被一個線程持有,且寫鎖存在時禁止讀鎖。
  • 使用場景:讀多寫少的場景(如緩存更新、配置讀取)。
  • 示例
    // 讀寫鎖示例
    private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    private Lock readLock = rwLock.readLock();
    private Lock writeLock = rwLock.writeLock();public void readData() {readLock.lock();try {// 讀取共享數據} finally {readLock.unlock();}
    }public void writeData() {writeLock.lock();try {// 修改共享數據} finally {writeLock.unlock();}
    }
    
10. 分段鎖(Striped Lock)
  • 核心思想:將鎖分段管理,不同段的鎖相互獨立,減少鎖競爭。
  • 實現方式
    • ConcurrentHashMap(JDK 7及以前):內部使用分段數組(Segment),每個Segment獨立加鎖;
    • JDK 8后改用CAS+Synchronized實現,但分段鎖思想仍在其他場景中使用。
  • 使用場景:大規模數據并發操作的場景(如分布式緩存)。

四、按鎖的特性擴展

11. 可中斷鎖(Interruptible Lock)
  • 核心思想:線程在等待鎖的過程中可被其他線程中斷。
  • 實現方式
    • ReentrantLocklockInterruptibly()方法;
    • synchronized不支持可中斷,只能通過Thread.interrupt()標記中斷狀態。
  • 使用場景:需要取消長時間等待的場景(如超時控制)。
  • 示例
    ReentrantLock lock = new ReentrantLock();
    try {lock.lockInterruptibly(); // 可中斷的鎖獲取try {// 操作共享資源} finally {lock.unlock();}
    } catch (InterruptedException e) {Thread.currentThread().interrupt(); // 恢復中斷狀態
    }
    
12. 鎖降級(Lock Degradation)
  • 核心思想:將寫鎖降級為讀鎖,保持數據可見性。
  • 實現方式
    • 先獲取寫鎖,修改數據后獲取讀鎖,再釋放寫鎖。
  • 使用場景:寫操作后需要保證后續讀操作可見性的場景(如緩存更新)。
  • 示例
    ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    Lock writeLock = rwLock.writeLock();
    Lock readLock = rwLock.readLock();public void updateAndRead() {writeLock.lock();try {// 修改數據readLock.lock(); // 獲取讀鎖} finally {writeLock.unlock(); // 釋放寫鎖,保留讀鎖(鎖降級)}try {// 讀取數據(確保數據可見性)} finally {readLock.unlock();}
    }
    

五、鎖的選擇策略

  1. 優先考慮無鎖方案:如使用Atomic類、ConcurrentHashMap等無鎖數據結構。
  2. 讀多寫少→樂觀鎖/CAS:沖突概率低時性能最優。
  3. 寫多沖突高→悲觀鎖:如synchronizedReentrantLock
  4. 鎖持有時間短→自旋鎖:避免線程上下文切換。
  5. 公平性需求→公平鎖:但需犧牲一定性能。
  6. 讀寫分離→讀寫鎖:如ReentrantReadWriteLock

理解各種鎖的特性和適用場景,結合具體業務需求選擇合適的鎖,是編寫高效并發代碼的關鍵。

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

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

相關文章

YOLOv11: AN OVERVIEW OF THE KEY ARCHITECTURAL ENHANCEMENTS目標檢測論文精讀(逐段解析)

YOLOv11: AN OVERVIEW OF THE KEY ARCHITECTURAL ENHANCEMENTS目標檢測論文精讀(逐段解析) 論文地址:https://www.arxiv.org/abs/2410.17725 Rahima Khanam and Muhammad Hussain Ultralytics公司發布 CVPR 2024 論文寫的比較簡單&#xff…

【Erdas實驗教程】025:遙感圖像輻射增強(霧霾去除)

文章目錄 一、霧霾去除原理二、霧霾去除案例一、霧霾去除原理 遙感影像霧霾去除的核心原理是消除大氣散射對電磁波的干擾,恢復地物真實反射信息。Haze Reduction 工具的原理: 該工具基于暗目標法(Dark Object Subtraction, DOS),適用于去除因大氣散射(霧霾本質是大氣顆…

Language Models are Unsupervised Multitask Learners :語言模型是無監督的多任務學習者

摘要 自然語言處理任務,如問答、機器翻譯、閱讀理解和摘要,通常通過在特定任務的數據集上進行監督學習來解決。我們展示了語言模型在訓練于一個包含數百萬網頁的新數據集——WebText——時,可以無需任何顯式監督就開始學習這些任務。當模型以…

SQL語句全攻略:從基礎到進階的編程之旅

目錄 一、引言二、SQL 基礎語法2.1 SQL 語句寫法順序2.2 關聯查詢2.3 數據處理常用函數和運算符 三、數據庫和表的基本操作3.1 創建數據庫3.2 使用數據庫3.3 創建表 四、基礎增刪改查操作4.1 插入數據(增)4.2 查詢數據(查)4.3 更新…

Kafka的下載安裝

目錄 一、前期準備 1、查看網卡: 2、配置靜態IP 3、設置主機名 4、配置IP與主機名映射 5、關閉防火墻 6、配置免密登錄 二、JDK的安裝 三、Zookeeper的安裝 四、Kafka的安裝 1、Kafka的下載安裝 2、修改配置文件 4、分發文件 5、修改其他節點broker.i…

opencv入門(6) TrackBar調整圖片和鍵盤響應

文章目錄 1 創建trackbar2 使用userdata傳入函數3 鍵盤響應 1 創建trackbar 1.trackbar名稱 2.創建在哪個窗口上 3.拖動trackbar改變的值 4.trackBar的最大值 5.trackbar改變時的回調函數 6. 帶入回調函數的數據,可以不用帶,是一個void指針 createTrackbar(“Value …

QT<33> 修改窗口標題欄背景顏色

前言: 在做項目或者開發QT軟件時,如果想要修改窗口標題欄背景顏色,發現沒有代碼可以直接設置,目前有兩種方法可以設置。 第一種,自定義一個界面類,用QLabelQWidget實現,QLabel當作標題欄。 第…

JavaEE-博客系統項目

項目介紹 準備工作 創建數據表 創建項目 添加依賴 創建對應目錄 除了基本的數據層mapper,業務層service,交互層controller,還創建了公共類的層common,枚舉類層enums,異常類層,和實體類層pojo。 配置項目配…

Java項目:基于SSM框架實現的軟件工程項目管理系統【ssm+B/S架構+源碼+數據庫+畢業論文+開題報告】

摘 要 現代經濟快節奏發展以及不斷完善升級的信息化技術,讓傳統數據信息的管理升級為軟件存儲,歸納,集中處理數據信息的管理方式。本項目管理系統就是在這樣的大環境下誕生,其可以幫助管理者在短時間內處理完畢龐大的數據信息&am…

[按鍵手機安卓/IOS腳本插件開發] 按鍵插件調試與判斷循環結構輔助工具

實現按鍵插件的核心原理 通過一個table類型的QMPlugin變量實現按鍵精靈調用Lua函數,例如 -- Lua代碼 -- 實現兩數相加求和 function QMPlugin.Add(a, b) return a b end 將以上代碼保存成.lua文件,例如test.lua后,放入按鍵精靈手機助手的p…

提示詞框架(9)--CARE

提示詞框架不止是AI的框架,也可以是我們的思考框架,拆解問題的方法!!! CARE框架是一種用于優化提示詞設計的方法,它幫助用戶更有效地與AI進行交互,特別是在需要獲取特定信息或實現某些任務時。…

uniapp+vue2 input不顯示明文密碼,點擊小眼睛顯示或隱藏密碼

<u-input placeholder"請輸入密碼" prefixIcon"lock" :password"showPassword" v-model"formData.password"prefixIconStyle"font-size: 25px;color: #3C9CFF" border"none"><template slot"suffix…

時間序列的類增量學習:基準與評估

論文地址&#xff1a;https://dl.acm.org/doi/abs/10.1145/3637528.3671581 論文源碼&#xff1a;https://github.com/zqiao11/TSCIL 會議&#xff1a;SIGKDD 2024&#xff08;CCF-A&#xff09; 現實環境本質上是非平穩的&#xff0c;隨著時間推移常會引入新類別。這在時間序…

智能攻擊原理和架構

大家讀完覺得有幫助記得關注和點贊&#xff01;&#xff01;&#xff01; 智能攻擊系統基于**人工智能&#xff08;AI&#xff09;與大語言模型&#xff08;LLM&#xff09;技術**&#xff0c;通過**環境感知→自主決策→動態執行→對抗進化**的閉環架構實現高效網絡入侵。以下…

Beamer-LaTeX學習(教程批注版)【4】

眾所周知&#xff0c;隨著顯示器普及寬屏化&#xff0c;PPT排版需要多列化來充分利用頁面的橫向空間。 這節課我們來學習如何創建列&#xff0c;即在beamer中增加列內容&#xff0c;以及如何對齊列。 1 使用不同的寬度來創建列 在beamer中我們通過在頁面上使用columns環境來創…

通俗理解JVM細節-面試篇

文章目錄 前言JVM概述JVM是什么&#xff1f;解決了什么問題&#xff1f;JVM運行流程JVM 與 JRE&#xff0c;JDK的關系 JVM內存結構JVM區域劃分程序計數器棧堆方法區 類加載機制五個階段加載驗證準備解析初始化總結雙親委派模型 垃圾回收內存管理什么是GC&#xff1f;如何判定誰…

意識邊疆保衛戰:22:47深圳AI-BioFab人機融合危機全息實錄

前言 前些天發現了一個巨牛的人工智能免費學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到網站 &#x1f9e0;《意識邊疆保衛戰&#xff1a;22&#xff1a;47深圳AI-BioFab人機融合危機全息實錄》 副標題&#xff1a;機械義…

langchain從入門到精通(三十四)——RAG優化策略(十)父文檔檢索器實現拆分和存儲平衡

1. 拆分文檔與檢索的沖突 在 RAG 應用開發中&#xff0c;文檔拆分 和 文檔檢索 通常存在相互沖突的愿望&#xff0c;例如&#xff1a; 我們可能希望擁有小型文檔&#xff0c;以便它們的嵌入可以最準確地反映它們的含義&#xff0c;如果太長&#xff0c;嵌入/向量沒法記錄太多…

Javaweb - 7 xml

XML 是EXtensible Markup Language 的縮寫&#xff0c;翻譯過來就是可擴展標記語言。即&#xff0c;XML 和 HTML 一樣&#xff0c;都是標記語言&#xff0c;也就是說&#xff0c;它們的基本語法都是標簽。 特點&#xff1a; 1. 可擴展&#xff1a;即 XML 是允許自定義格式的。但…

qml實現 裁剪進度條

我們需要實現一個垂直進度條效果&#xff0c;但使用圖片裁剪的方式。具體需求&#xff1a; 1. 圖片位置固定&#xff0c;容器對齊其左邊和下邊&#xff0c;寬度和圖片相同。 2. 容器背景透明&#xff0c;調整裁剪容器的高度&#xff0c;使其有高度進度條的感覺&#xff08;從下…