欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間: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)存可見(jiàn)性等常見(jiàn)問(wèn)題的實(shí)踐指南,感興趣的朋友跟隨小編一起看看吧

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

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

多線程編程可以帶來(lái)諸多好處:

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

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

一、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() 才是啟動(dòng)新線程

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:新建但未啟動(dòng)
  • RUNNABLE:可運(yùn)行狀態(tài)(包括正在運(yùn)行和準(zhǔn)備運(yùn)行)
  • BLOCKED:等待監(jiān)視器鎖(同步塊/方法)
  • WAITING:無(wú)限期等待(Object.wait()、Thread.join()等)
  • TIMED_WAITING:有限期等待(Thread.sleep()、帶超時(shí)的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) { // 可以使用任何對(duì)象作為鎖
        // 臨界區(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)的,簡(jiǎn)單但功能有限
  • Lock 接口提供了更多功能,如嘗試獲取鎖、公平鎖等

2.2 volatile 關(guān)鍵字

volatile 保證變量的可見(jiàn)性,但不保證原子性:

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開(kāi)始工作
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, // 空閑線程存活時(shí)間
    TimeUnit.SECONDS, // 時(shí)間單位
    new ArrayBlockingQueue<>(100), // 工作隊(duì)列
    new ThreadPoolExecutor.CallerRunsPolicy() // 拒絕策略
);

5.3 拒絕策略

  • AbortPolicy:默認(rèn)策略,直接拋出 RejectedExecutionException
  • CallerRunsPolicy:用調(diào)用者所在線程來(lái)執(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");
// 適合讀多寫(xiě)少的場(chǎng)景

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í)踐與常見(jiàn)問(wèn)題

8.1 最佳實(shí)踐

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

8.2 常見(jiàn)問(wèn)題

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

結(jié)語(yǔ)

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

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

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

相關(guān)文章

  • Java與Unix時(shí)間戳的相互轉(zhuǎn)換詳解

    Java與Unix時(shí)間戳的相互轉(zhuǎn)換詳解

    這篇文章主要為大家詳細(xì)介紹了Java與Unix時(shí)間戳的相互轉(zhuǎn)換,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • mybatis中嵌套查詢的使用解讀

    mybatis中嵌套查詢的使用解讀

    這篇文章主要介紹了mybatis中嵌套查詢的使用解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • JAVA-NIO之Socket/ServerSocket Channel(詳解)

    JAVA-NIO之Socket/ServerSocket Channel(詳解)

    下面小編就為大家?guī)?lái)一篇JAVA-NIO之Socket/ServerSocket Channel(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • Java虛擬機(jī)之雙親委派機(jī)制詳解

    Java虛擬機(jī)之雙親委派機(jī)制詳解

    這篇文章主要為大家介紹了Java虛擬機(jī)之雙親委派機(jī)制,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-12-12
  • idea 有時(shí)提示找不到類或者符號(hào)的解決

    idea 有時(shí)提示找不到類或者符號(hào)的解決

    這篇文章主要介紹了idea 有時(shí)提示找不到類或者符號(hào)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09
  • SpringBoot動(dòng)態(tài)修改日志級(jí)別的操作

    SpringBoot動(dòng)態(tài)修改日志級(jí)別的操作

    這篇文章主要介紹了SpringBoot動(dòng)態(tài)修改日志級(jí)別的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • JavaAgent的簡(jiǎn)單例子

    JavaAgent的簡(jiǎn)單例子

    這篇文章主要介紹了JavaAgent的簡(jiǎn)單例子,對(duì)JavaAgent感興趣的同學(xué),可以參考下
    2021-04-04
  • java數(shù)據(jù)結(jié)構(gòu)排序算法之歸并排序詳解

    java數(shù)據(jù)結(jié)構(gòu)排序算法之歸并排序詳解

    這篇文章主要介紹了java數(shù)據(jù)結(jié)構(gòu)排序算法之歸并排序,結(jié)合具體實(shí)例形式詳細(xì)分析了歸并排序的原理、實(shí)現(xiàn)技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-05-05
  • java.net.http.HttpClient使用示例解析

    java.net.http.HttpClient使用示例解析

    這篇文章主要為大家介紹了java.net.http.HttpClient使用示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • 利用Java+MySQL實(shí)現(xiàn)附近功能實(shí)例

    利用Java+MySQL實(shí)現(xiàn)附近功能實(shí)例

    現(xiàn)在很多手機(jī)軟件都用附近搜索功能,但具體是怎么實(shí)現(xiàn)的呢?下面這篇文章就來(lái)給大家介紹關(guān)于利用Java+MySQL實(shí)現(xiàn)附近功能的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-12-12

最新評(píng)論