最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java 多線程與并發(fā)編程全面實(shí)戰(zhàn)指南

 更新時間:2025年09月15日 14:44:19   作者:vvilkin  
本文系統(tǒng)講解Java多線程與并發(fā)編程,涵蓋線程創(chuàng)建、同步機(jī)制(synchronized/Lock)、通信工具、并發(fā)集合、線程池及CompletableFuture等現(xiàn)代技術(shù),強(qiáng)調(diào)正確使用多線程的重要性,提供避免死鎖、內(nèi)存可見性等常見問題的實(shí)踐指南,感興趣的朋友跟隨小編一起看看吧

引言:為什么需要多線程?

在當(dāng)今這個多核處理器普及的時代,單線程程序已經(jīng)難以充分利用現(xiàn)代計(jì)算機(jī)硬件的計(jì)算能力。Java 作為一門成熟的企業(yè)級編程語言,提供了豐富的多線程與并發(fā)編程支持,使開發(fā)者能夠構(gòu)建高性能、高并發(fā)的應(yīng)用程序。

多線程編程可以帶來諸多好處:

  • 提高 CPU 利用率:在多核系統(tǒng)上并行執(zhí)行任務(wù)
  • 提高程序響應(yīng)性:GUI 應(yīng)用可以保持界面響應(yīng)同時執(zhí)行后臺任務(wù)
  • 簡化建模:某些問題(如服務(wù)器處理多個客戶端請求)用多線程模型更自然
  • 提高吞吐量:通過并行處理提高系統(tǒng)整體處理能力

然而,多線程編程也帶來了復(fù)雜性,包括線程安全、死鎖、競態(tài)條件等問題。本文將全面介紹 Java 多線程與并發(fā)編程的各個方面。

一、Java 線程基礎(chǔ)

1.1 線程創(chuàng)建方式

Java 提供了三種基本的線程創(chuàng)建方式:

1.1.1 繼承 Thread 類

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("Thread running: " + Thread.currentThread().getName());
    }
}
// 使用
MyThread thread = new MyThread();
thread.start(); // 注意:調(diào)用 run() 是普通方法調(diào)用,start() 才是啟動新線程

1.1.2 實(shí)現(xiàn) Runnable 接口

class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("Runnable running: " + Thread.currentThread().getName());
    }
}
// 使用
Thread thread = new Thread(new MyRunnable());
thread.start();

1.1.3 實(shí)現(xiàn) Callable 接口

class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        return "Result from " + Thread.currentThread().getName();
    }
}
// 使用
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new MyCallable());
System.out.println(future.get()); // 獲取返回值
executor.shutdown();

最佳實(shí)踐:推薦實(shí)現(xiàn) Runnable 或 Callable 接口,因?yàn)?Java 不支持多重繼承,且這種方式更符合面向?qū)ο蟮脑O(shè)計(jì)原則。

1.2 線程生命周期

Java 線程有以下幾種狀態(tài):

  • NEW:新建但未啟動
  • RUNNABLE:可運(yùn)行狀態(tài)(包括正在運(yùn)行和準(zhǔn)備運(yùn)行)
  • BLOCKED:等待監(jiān)視器鎖(同步塊/方法)
  • WAITING:無限期等待(Object.wait()、Thread.join()等)
  • TIMED_WAITING:有限期等待(Thread.sleep()、帶超時的wait/join等)
  • TERMINATED:線程執(zhí)行完畢
Thread thread = new Thread(() -> {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
});
System.out.println(thread.getState()); // NEW
thread.start();
System.out.println(thread.getState()); // RUNNABLE
Thread.sleep(500);
System.out.println(thread.getState()); // TIMED_WAITING
Thread.sleep(1000);
System.out.println(thread.getState()); // TERMINATED

二、線程同步與線程安全

2.1 同步機(jī)制

2.1.1 synchronized 關(guān)鍵字

// 同步方法
public synchronized void syncMethod() {
    // 臨界區(qū)代碼
}
// 同步代碼塊
public void someMethod() {
    synchronized(this) { // 可以使用任何對象作為鎖
        // 臨界區(qū)代碼
    }
}

2.1.2 Lock 接口

Lock lock = new ReentrantLock();
public void someMethod() {
    lock.lock();
    try {
        // 臨界區(qū)代碼
    } finally {
        lock.unlock(); // 確保在finally中釋放鎖
    }
}

比較

  • synchronized 是 JVM 實(shí)現(xiàn)的,簡單但功能有限
  • Lock 接口提供了更多功能,如嘗試獲取鎖、公平鎖等

2.2 volatile 關(guān)鍵字

volatile 保證變量的可見性,但不保證原子性:

private volatile boolean running = true;
public void stop() {
    running = false;
}
public void run() {
    while(running) {
        // 執(zhí)行任務(wù)
    }
}

2.3 原子類

java.util.concurrent.atomic 包提供了一系列原子類:

AtomicInteger counter = new AtomicInteger(0);
// 線程安全的自增
counter.incrementAndGet();
// CAS 操作
boolean updated = counter.compareAndSet(expect, update);

三、線程通信

3.1 wait/notify 機(jī)制

class SharedResource {
    private boolean ready = false;
    public synchronized void waitForReady() throws InterruptedException {
        while(!ready) {
            wait(); // 釋放鎖并等待
        }
        // 條件滿足,繼續(xù)執(zhí)行
    }
    public synchronized void setReady() {
        ready = true;
        notifyAll(); // 通知所有等待線程
    }
}

3.2 Condition 接口

class BoundedBuffer {
    final Lock lock = new ReentrantLock();
    final Condition notFull = lock.newCondition();
    final Condition notEmpty = lock.newCondition();
    final Object[] items = new Object[100];
    int putptr, takeptr, count;
    public void put(Object x) throws InterruptedException {
        lock.lock();
        try {
            while (count == items.length)
                notFull.await();
            items[putptr] = x;
            if (++putptr == items.length) putptr = 0;
            ++count;
            notEmpty.signal();
        } finally {
            lock.unlock();
        }
    }
    public Object take() throws InterruptedException {
        lock.lock();
        try {
            while (count == 0)
                notEmpty.await();
            Object x = items[takeptr];
            if (++takeptr == items.length) takeptr = 0;
            --count;
            notFull.signal();
            return x;
        } finally {
            lock.unlock();
        }
    }
}

四、并發(fā)工具類

4.1 CountDownLatch

CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(N);
for (int i = 0; i < N; ++i) {
    new Thread(new Worker(startSignal, doneSignal)).start();
}
doSomethingElse(); // 主線程準(zhǔn)備工作
startSignal.countDown(); // 讓所有worker開始工作
doSomethingElse();
doneSignal.await(); // 等待所有worker完成

4.2 CyclicBarrier

class Solver {
    final int N;
    final float[][] data;
    final CyclicBarrier barrier;
    class Worker implements Runnable {
        int myRow;
        Worker(int row) { myRow = row; }
        public void run() {
            while (!done()) {
                processRow(myRow);
                try {
                    barrier.await();
                } catch (InterruptedException ex) {
                    return;
                } catch (BrokenBarrierException ex) {
                    return;
                }
            }
        }
    }
    public Solver(float[][] matrix) {
        data = matrix;
        N = matrix.length;
        barrier = new CyclicBarrier(N, () -> {
            mergeRows();
        });
        for (int i = 0; i < N; ++i)
            new Thread(new Worker(i)).start();
    }
}

4.3 Semaphore

class Pool {
    private static final int MAX_AVAILABLE = 100;
    private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
    public Object getItem() throws InterruptedException {
        available.acquire();
        return getNextAvailableItem();
    }
    public void putItem(Object x) {
        if (markAsUnused(x))
            available.release();
    }
}

五、線程池

5.1 線程池創(chuàng)建

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);

5.2 ThreadPoolExecutor

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    5, // 核心線程數(shù)
    10, // 最大線程數(shù)
    60, // 空閑線程存活時間
    TimeUnit.SECONDS, // 時間單位
    new ArrayBlockingQueue<>(100), // 工作隊(duì)列
    new ThreadPoolExecutor.CallerRunsPolicy() // 拒絕策略
);

5.3 拒絕策略

  • AbortPolicy:默認(rèn)策略,直接拋出 RejectedExecutionException
  • CallerRunsPolicy:用調(diào)用者所在線程來執(zhí)行任務(wù)
  • DiscardPolicy:直接丟棄任務(wù)
  • DiscardOldestPolicy:丟棄隊(duì)列中最老的任務(wù),然后嘗試提交新任務(wù)

六、并發(fā)集合

6.1 ConcurrentHashMap

ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("key", 1);
map.compute("key", (k, v) -> v + 1); // 原子更新

6.2 CopyOnWriteArrayList

CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
list.add("item");
// 適合讀多寫少的場景

6.3 BlockingQueue

BlockingQueue<String> queue = new LinkedBlockingQueue<>(10);
// 生產(chǎn)者
queue.put("item");
// 消費(fèi)者
String item = queue.take();

七、現(xiàn)代并發(fā)編程

7.1 CompletableFuture

CompletableFuture.supplyAsync(() -> fetchData())
    .thenApply(data -> processData(data))
    .thenAccept(result -> displayResult(result))
    .exceptionally(ex -> {
        System.err.println("Error: " + ex.getMessage());
        return null;
    });

7.2 并行流

List<String> results = dataList.parallelStream()
    .filter(item -> item.startsWith("A"))
    .map(String::toUpperCase)
    .collect(Collectors.toList());

八、最佳實(shí)踐與常見問題

8.1 最佳實(shí)踐

  • 優(yōu)先使用高級并發(fā)工具:如并發(fā)集合、線程池等
  • 避免過度同步:同步范圍越小越好
  • 使用不可變對象:簡化線程安全設(shè)計(jì)
  • 注意資源清理:確保線程池和資源正確關(guān)閉
  • 考慮使用無鎖算法:如原子變量類

8.2 常見問題

  • 死鎖:多個線程互相等待對方釋放鎖
    • 避免方法:按固定順序獲取鎖,使用帶超時的鎖
  • 活鎖:線程不斷重試失敗的操作
    • 避免方法:引入隨機(jī)退避時間
  • 線程饑餓:某些線程長期得不到執(zhí)行
    • 解決方法:使用公平鎖或調(diào)整線程優(yōu)先級
  • 內(nèi)存可見性問題:一個線程的修改對另一個線程不可見
    • 解決方法:使用 volatile 或適當(dāng)同步

結(jié)語

Java 多線程與并發(fā)編程是一個既強(qiáng)大又復(fù)雜的主題。掌握這些技術(shù)可以幫助開發(fā)者構(gòu)建高性能、高并發(fā)的應(yīng)用程序,但也需要謹(jǐn)慎處理線程安全和性能問題。隨著 Java 版本的更新,并發(fā)編程的 API 也在不斷改進(jìn)和簡化(如 CompletableFuture、并行流等),開發(fā)者應(yīng)當(dāng)持續(xù)學(xué)習(xí)這些新特性。

記住,多線程編程的第一原則是:如果可以不使用多線程,就不要使用多線程。只有在真正需要并行處理或異步操作時,才考慮引入多線程,并且要確保正確處理所有并發(fā)問題。

到此這篇關(guān)于Java 多線程與并發(fā)編程全面指南的文章就介紹到這了,更多相關(guān)Java 多線程與并發(fā)編程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot Admin的簡單使用的方法步驟

    SpringBoot Admin的簡單使用的方法步驟

    本文主要介紹了SpringBoot Admin的簡單使用的方法步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Java中保證線程順序執(zhí)行的四種實(shí)現(xiàn)方式

    Java中保證線程順序執(zhí)行的四種實(shí)現(xiàn)方式

    在多線程編程中,線程的并發(fā)執(zhí)行通常是不可預(yù)知的,然而在某些應(yīng)用場景中,我們需要確保多個線程按特定的順序執(zhí)行,本文將介紹幾種常見的方式,幫助我們在多線程中保證執(zhí)行順序,需要的朋友可以參考下
    2025-08-08
  • 關(guān)于servlet向mysql添加數(shù)據(jù)時中文亂碼問題的解決

    關(guān)于servlet向mysql添加數(shù)據(jù)時中文亂碼問題的解決

    最近在工作中遇到一個小問題,出現(xiàn)了中文亂碼的問題,無奈只能想辦法解決,下面這篇文章主要給大家介紹了關(guān)于servlet向mysql添加數(shù)據(jù)時中文亂碼問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-08-08
  • kafka消費(fèi)不到數(shù)據(jù)的排查過程

    kafka消費(fèi)不到數(shù)據(jù)的排查過程

    這篇文章主要介紹了kafka消費(fèi)不到數(shù)據(jù)的排查過程,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 詳述IntelliJ IDEA插件的安裝及使用方法(圖解)

    詳述IntelliJ IDEA插件的安裝及使用方法(圖解)

    本篇文章主要介紹了詳述 IntelliJ IDEA 插件的安裝及使用方法(圖解),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • SpringBoot自定義Redis實(shí)現(xiàn)緩存序列化詳解

    SpringBoot自定義Redis實(shí)現(xiàn)緩存序列化詳解

    Spring提供了一個RedisTemplate來進(jìn)行對Redis的操作,但是RedisTemplate默認(rèn)配置的是使用Java本機(jī)序列化。如果要對對象操作,就不是那么的方便。所以本文為大家介紹了另一種SpringBoot結(jié)合Redis實(shí)現(xiàn)序列化的方法,需要的可以參考一下
    2022-07-07
  • 學(xué)習(xí)java一定要知道的垃圾收集器

    學(xué)習(xí)java一定要知道的垃圾收集器

    這篇文章主要介紹了學(xué)習(xí)java一定要知道的垃圾收集器,垃圾收集器的發(fā)展路線,簡單來說是隨著內(nèi)存越來越大而發(fā)生變化,更多相關(guān)介紹需要的朋友可以參考一下
    2022-07-07
  • Java讀取properties文件內(nèi)容的幾種方式詳解

    Java讀取properties文件內(nèi)容的幾種方式詳解

    這篇文章主要介紹了Java讀取properties文件內(nèi)容的幾種方式詳解,讀取properties配置文件在實(shí)際的開發(fā)中使用的很多,本文來介紹常用的幾種實(shí)現(xiàn)方式,需要的朋友可以參考下
    2023-11-11
  • JavaWeb文件上傳下載功能示例解析

    JavaWeb文件上傳下載功能示例解析

    這篇文章主要介紹了JavaWeb中的文件上傳和下載功能的實(shí)現(xiàn),文件上傳和下載功能是非常常用的功能,需要的朋友可以參考下
    2016-06-06
  • Spring Boot整合Lombok的方法詳解

    Spring Boot整合Lombok的方法詳解

    Lombok 是一種 Java 實(shí)用工具,可用來幫助開發(fā)人員消除 Java 的冗長,尤其是對于簡單的 Java 對象(POJO)。這篇文章主要介紹了Spring Boot整合Lombok,需要的朋友可以參考下
    2021-04-04

最新評論

丰镇市| 罗江县| 乐昌市| 鄂伦春自治旗| 凤翔县| 定边县| 罗平县| 台湾省| 峨边| 富顺县| 白河县| 通海县| 瑞金市| 恭城| 且末县| 小金县| 绥德县| 高邮市| 清镇市| 渝北区| 克什克腾旗| 郧西县| 江山市| 九台市| 寿阳县| 虎林市| 武定县| 双鸭山市| 孙吴县| 叶城县| 台前县| 平遥县| 久治县| 志丹县| 惠来县| 宜春市| 长子县| 昭通市| 江永县| 响水县| 南康市|