Java多線程

一、基礎(chǔ)概念

1.進程與線程

進程:操作系統(tǒng)資源分配的基本單位,擁有獨立的內(nèi)存空間(如代碼段、堆、方法區(qū))。

線程:進程內(nèi)的執(zhí)行單元,是CPU調(diào)度的最小單位,共享進程資源(如堆內(nèi)存),但擁有獨立的棧空間。

單線程 vs 多線程:單線程按順序執(zhí)行任務(wù),多線程通過并發(fā)/并行提升性能(需多核CPU支持并行)。

2.并發(fā)與并行

并發(fā):單核CPU通過時間片輪轉(zhuǎn)模擬多任務(wù)交替執(zhí)行。

并行:多核CPU同時執(zhí)行多個任務(wù)。

二、線程的創(chuàng)建與啟動

Java提供兩種核心方式創(chuàng)建線程:

1.繼承Thread類

class MyThread extends Thread {

? ? @Override

? ? public void run() {

? ? ? ? System.out.println("線程執(zhí)行中:" + Thread.currentThread().getName());

? ? }

}

// 啟動線程

public static void main(String[] args) {

? ? MyThread t = new MyThread();

? ? t.start();? // 啟動新線程

}

特點:簡單但受限于單繼承。

2.實現(xiàn)Runnable接口

class MyRunnable implements Runnable {

? ? @Override

? ? public void run() {

? ? ? ? System.out.println("任務(wù)執(zhí)行中:" + Thread.currentThread().getName());

? ? }

}

// 啟動線程

public static void main(String[] args) {

? ? Thread t = new Thread(new MyRunnable());

? ? t.start();

}

優(yōu)勢:避免單繼承限制,支持資源共享。

3.其他方式

Lambda表達式(Java 8+):簡化代碼,如?new Thread(() -> System.out.println("Lambda線程")).start();

Callable接口:支持返回值和異常處理,需配合Future使用。

三、線程生命周期與狀態(tài)

線程狀態(tài)包括:

NEW(新建) → RUNNABLE(就緒) → RUNNING(運行) → BLOCKED(阻塞) → WAITING(等待) → TIMED_WAITING(計時等待) → TERMINATED(終止)。

關(guān)鍵方法

join():等待線程結(jié)束(如主線程等待子線程完成)。

setPriority():設(shè)置優(yōu)先級(1-10,默認5)。

sleep():暫停線程執(zhí)行(單位:毫秒)。

setDaemon(true):設(shè)為守護線程(主線程退出時自動終止)。

四、線程同步與并發(fā)安全

多線程共享資源時需解決數(shù)據(jù)競爭問題:

1.同步代碼塊

synchronized (lockObject) {

? ? // 臨界區(qū)代碼

}

原理:基于對象監(jiān)視器鎖(Monitor Lock),確保同一時間僅一個線程訪問臨界區(qū)。

2.同步方法

public synchronized void method() {

? ? // 同步方法體

}

等價于:synchronized (this)。

3.Lock接口

ReentrantLock lock = new ReentrantLock();

lock.lock();

try {

? ? // 臨界區(qū)操作

} finally {

? ? lock.unlock();? // 必須釋放鎖

}

優(yōu)勢:支持公平鎖、可中斷鎖等高級特性。

4.原子類

AtomicInteger counter = new AtomicInteger(0);

int value = counter.incrementAndGet();? // 原子遞增

原理:基于CAS(Compare-And-Swap)實現(xiàn)無鎖并發(fā)。

五、線程池技術(shù)

作用:復(fù)用線程,減少創(chuàng)建/銷毀開銷,提升性能。

1.核心參數(shù)

corePoolSize:核心線程數(shù)(常駐)。

maximumPoolSize:最大線程數(shù)。

workQueue:任務(wù)隊列(如LinkedBlockingQueue)。

RejectedExecutionHandler:拒絕策略(如丟棄、拋異常)。

2.創(chuàng)建線程池

ExecutorService executor = Executors.newFixedThreadPool(5); // 固定線程池

executor.submit(() -> System.out.println("任務(wù)提交"));

executor.shutdown();? // 優(yōu)雅關(guān)閉

3.線程池類型

FixedThreadPool:固定線程數(shù)。

CachedThreadPool:彈性線程池(自動回收空閑線程)。

ScheduledThreadPool:支持定時任務(wù)。

六、高級并發(fā)工具

1.CountDownLatch

CountDownLatch latch = new CountDownLatch(3);

// 等待3個線程完成

latch.await();

用途:主線程等待多個子線程完成。

2.CyclicBarrier

CyclicBarrier barrier = new CyclicBarrier(3, () -> System.out.println("所有線程就緒"));

// 多個線程相互等待后同步執(zhí)行

barrier.await();

用途:多線程協(xié)同執(zhí)行任務(wù)。

3.ConcurrentHashMap

線程安全哈希表,通過分段鎖(JDK 1.7)或CAS(JDK 1.8)實現(xiàn)高并發(fā)性能。

七、注意事項

避免死鎖:按固定順序獲取鎖,或使用tryLock()超時機制。

線程中斷:通過interrupt()方法中斷線程,需配合狀態(tài)檢查(如isInterrupted())。

資源競爭:減少鎖粒度,優(yōu)先使用無鎖數(shù)據(jù)結(jié)構(gòu)(如ConcurrentLinkedQueue)。

示例:多線程售票系統(tǒng)

class TicketSystem implements Runnable {

? ? private int tickets = 100;

? ? private final Object lock = new Object();

? ? @Override

? ? public void run() {

? ? ? ? while (true) {

? ? ? ? ? ? synchronized (lock) {

? ? ? ? ? ? ? ? if (tickets <= 0) break;

? ? ? ? ? ? ? ? System.out.println(Thread.currentThread().getName() + "售出第" + tickets--);

? ? ? ? ? ? }

? ? ? ? ? ? try {

? ? ? ? ? ? ? ? Thread.sleep(100);? // 模擬售票耗時

? ? ? ? ? ? } catch (InterruptedException e) {

? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

public class Main {

? ? public static void main(String[] args) {

? ? ? ? Thread t1 = new Thread(new TicketSystem(), "窗口1");

? ? ? ? Thread t2 = new Thread(new TicketSystem(), "窗口2");

? ? ? ? t1.start();

? ? ? ? t2.start();

? ? }

}

輸出:多個線程交替售出票號,保證數(shù)據(jù)一致性。

通過合理使用線程創(chuàng)建、同步機制和并發(fā)工具,Java多線程編程可顯著提升程序性能,但需謹慎處理資源競爭與線程安全問題。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 進程和線程 操作系統(tǒng)中運行多個軟件,一個運行中的軟件可能包含多個進程,一個運行中的進程可能包含多個線程。 進程 ...
    angeliur閱讀 677評論 0 0
  • 本文主要基于 高洪巖《Java多線程編程核心技術(shù)》一書,文章目錄基本與書保持一致,由于想偷懶就將看書過程中的md筆...
    LeonardoEzio閱讀 1,198評論 2 3
  • 進程和線程 進程 所有運行中的任務(wù)通常對應(yīng)一個進程,當一個程序進入內(nèi)存運行時,即變成一個進程.進程是處于運行過程中...
    勝浩_ae28閱讀 5,261評論 0 23
  • 1. 線程的基本概念 1.1 進程 任何的軟件存儲在磁盤中,運行軟件的時候,OS使用IO技術(shù),將磁盤中的軟件的文件...
    Zzzzjq閱讀 407評論 0 0
  • 前言 本文會介紹Java中多線程與并發(fā)的基礎(chǔ),適合初學(xué)者食用,如果想看關(guān)于多線程與并發(fā)稍微進階一些的內(nèi)容可以看我的...
    ObjectSpace閱讀 490評論 0 5

友情鏈接更多精彩內(nèi)容