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

Java并發(fā)編程最佳實(shí)踐之構(gòu)建高并發(fā)、可伸縮的應(yīng)用實(shí)例

 更新時(shí)間:2026年04月19日 09:36:03   作者:程序員鴨梨  
Java并發(fā)編程是Java語(yǔ)言中最為復(fù)雜且核心的高級(jí)特性之一,其本質(zhì)在于如何在多線程環(huán)境下高效、安全、可預(yù)測(cè)地協(xié)調(diào)多個(gè)執(zhí)行單元對(duì)共享資源的訪問(wèn)與協(xié)作,這篇文章主要介紹了Java并發(fā)編程最佳實(shí)踐之構(gòu)建高并發(fā)、可伸縮的應(yīng)用實(shí)例,需要的朋友可以參考下

一、引言

在現(xiàn)代應(yīng)用開(kāi)發(fā)中,并發(fā)編程已經(jīng)成為一個(gè)不可或缺的技能。隨著多核處理器的普及,充分利用系統(tǒng)資源、提高應(yīng)用性能成為了開(kāi)發(fā)者的重要目標(biāo)。Java 作為企業(yè)級(jí)應(yīng)用的主流語(yǔ)言,提供了豐富的并發(fā)編程工具和 API。今天,我想和大家分享一下 Java 并發(fā)編程的最佳實(shí)踐,幫助大家構(gòu)建高并發(fā)、可伸縮的應(yīng)用。

二、并發(fā)編程基礎(chǔ)

1. 線程安全

  • 原子性:操作要么全部執(zhí)行,要么全部不執(zhí)行
  • 可見(jiàn)性:一個(gè)線程對(duì)共享變量的修改,其他線程能夠立即看到
  • 有序性:程序執(zhí)行的順序按照代碼的先后順序執(zhí)行

2. 并發(fā)工具類(lèi)

基本工具

  • synchronized:同步關(guān)鍵字
  • volatile:保證可見(jiàn)性
  • final:不可變對(duì)象

并發(fā)集合

  • ConcurrentHashMap:線程安全的哈希表
  • CopyOnWriteArrayList:寫(xiě)時(shí)復(fù)制的數(shù)組
  • BlockingQueue:阻塞隊(duì)列

線程池

  • Executors:線程池工廠
  • ThreadPoolExecutor:線程池實(shí)現(xiàn)

三、最佳實(shí)踐

1. 線程池使用

合理配置線程池

// 好的做法
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    corePoolSize,          // 核心線程數(shù)
    maximumPoolSize,       // 最大線程數(shù)
    keepAliveTime,         // 線程存活時(shí)間
    TimeUnit.SECONDS,      // 時(shí)間單位
    new LinkedBlockingQueue<>(queueCapacity), // 任務(wù)隊(duì)列
    new ThreadFactoryBuilder().setNameFormat("worker-%d").build(), // 線程工廠
    new ThreadPoolExecutor.CallerRunsPolicy() // 拒絕策略
);

// 不好的做法
ExecutorService executor = Executors.newFixedThreadPool(10); // 可能導(dǎo)致 OOM

線程池監(jiān)控

@Bean
public ThreadPoolTaskExecutor taskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(10);
    executor.setMaxPoolSize(20);
    executor.setQueueCapacity(100);
    executor.setThreadNamePrefix("task-");
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    executor.initialize();
    return executor;
}

2. 鎖的使用

選擇合適的鎖

  • synchronized:適合簡(jiǎn)單場(chǎng)景
  • ReentrantLock:適合復(fù)雜場(chǎng)景,支持公平鎖和非公平鎖
  • ReadWriteLock:適合讀多寫(xiě)少的場(chǎng)景
  • StampedLock:JDK 8+ 提供,性能更好

鎖優(yōu)化

  • 減少鎖的范圍:只鎖定必要的代碼塊
  • 使用無(wú)鎖數(shù)據(jù)結(jié)構(gòu):如 Atomic 類(lèi)
  • 避免死鎖:合理安排鎖的獲取順序

示例

// 好的做法
public class Counter {
    private final AtomicInteger count = new AtomicInteger(0);
    public void increment() {
        count.incrementAndGet();
    }
    public int getCount() {
        return count.get();
    }
}
// 不好的做法
public class Counter {
    private int count = 0;
    public synchronized void increment() {
        count++;
    }
    public synchronized int getCount() {
        return count;
    }
}

3. 并發(fā)集合使用

選擇合適的集合

場(chǎng)景推薦集合
高并發(fā)讀寫(xiě)ConcurrentHashMap
讀多寫(xiě)少CopyOnWriteArrayList
生產(chǎn)者-消費(fèi)者BlockingQueue
線程安全隊(duì)列ConcurrentLinkedQueue

示例

// 高并發(fā)讀寫(xiě)
private final Map<String, User> userMap = new ConcurrentHashMap<>();
// 讀多寫(xiě)少
private final List<User> userList = new CopyOnWriteArrayList<>();
// 生產(chǎn)者-消費(fèi)者
private final BlockingQueue<Message> messageQueue = new LinkedBlockingQueue<>();

4. 線程安全的單例模式

枚舉單例

// 最佳實(shí)踐
public enum Singleton {
    INSTANCE;
    private final UserService userService;
    Singleton() {
        userService = new UserService();
    }
    public UserService getUserService() {
        return userService;
    }
}
// 使用
UserService userService = Singleton.INSTANCE.getUserService();

雙重檢查鎖

public class Singleton {
    private static volatile Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

5. 原子操作

Atomic 類(lèi)

  • AtomicInteger:原子整數(shù)
  • AtomicLong:原子長(zhǎng)整型
  • AtomicReference:原子引用
  • AtomicStampedReference:帶版本號(hào)的原子引用

示例

// 原子更新
AtomicInteger counter = new AtomicInteger(0);
// 遞增
int value = counter.incrementAndGet();
// 比較并交換
boolean updated = counter.compareAndSet(expectedValue, newValue);

6. 并發(fā)工具

CountDownLatch

// 等待多個(gè)線程完成
CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
    executor.submit(() -> {
        try {
            // 執(zhí)行任務(wù)
        } finally {
            latch.countDown();
        }
    });
}
// 等待所有任務(wù)完成
latch.await();

CyclicBarrier

// 等待多個(gè)線程到達(dá)屏障
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
    System.out.println("所有線程已到達(dá)屏障");
});
for (int i = 0; i < 3; i++) {
    executor.submit(() -> {
        try {
            // 執(zhí)行任務(wù)
            barrier.await();
            // 繼續(xù)執(zhí)行
        } catch (Exception e) {
            e.printStackTrace();
        }
    });
}

Semaphore

// 控制并發(fā)訪問(wèn)數(shù)
Semaphore semaphore = new Semaphore(5);
for (int i = 0; i < 10; i++) {
    executor.submit(() -> {
        try {
            semaphore.acquire();
            try {
                // 執(zhí)行任務(wù)
            } finally {
                semaphore.release();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
}

CompletableFuture

// 異步執(zhí)行
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
    // 執(zhí)行任務(wù)
    return "Result 1";
});
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
    // 執(zhí)行任務(wù)
    return "Result 2";
});
// 組合結(jié)果
CompletableFuture<String> combined = future1.thenCombine(future2, (result1, result2) -> {
    return result1 + ", " + result2;
});
// 獲取結(jié)果
String result = combined.join();

四、并發(fā)編程的挑戰(zhàn)

1. 死鎖

避免死鎖

  • 按固定順序獲取鎖
  • 使用超時(shí)機(jī)制
  • 使用 Lock 接口的 tryLock() 方法

示例

// 好的做法:按固定順序獲取鎖
public void transferMoney(Account from, Account to, int amount) {
    int fromHash = System.identityHashCode(from);
    int toHash = System.identityHashCode(to);
    if (fromHash < toHash) {
        synchronized (from) {
            synchronized (to) {
                from.debit(amount);
                to.credit(amount);
            }
        }
    } else if (fromHash > toHash) {
        synchronized (to) {
            synchronized (from) {
                from.debit(amount);
                to.credit(amount);
            }
        }
    } else {
        // 使用額外的鎖
        synchronized (lock) {
            synchronized (from) {
                synchronized (to) {
                    from.debit(amount);
                    to.credit(amount);
                }
            }
        }
    }
}

2. 活鎖

避免活鎖

  • 引入隨機(jī)延遲
  • 使用優(yōu)先級(jí)機(jī)制
  • 避免無(wú)限重試

3. 饑餓

避免饑餓

  • 使用公平鎖
  • 合理設(shè)置線程優(yōu)先級(jí)
  • 避免長(zhǎng)時(shí)間持有鎖

五、實(shí)戰(zhàn)案例

案例:電商系統(tǒng)庫(kù)存管理

需求

  • 高并發(fā)下的庫(kù)存管理
  • 避免超賣(mài)
  • 保證數(shù)據(jù)一致性

實(shí)現(xiàn)

public class InventoryService {
    private final ConcurrentHashMap<String, AtomicInteger> inventory = new ConcurrentHashMap<>();
    public boolean decreaseStock(String productId, int quantity) {
        AtomicInteger stock = inventory.computeIfAbsent(productId, k -> new AtomicInteger(0));
        while (true) {
            int currentStock = stock.get();
            if (currentStock < quantity) {
                return false; // 庫(kù)存不足
            }
            if (stock.compareAndSet(currentStock, currentStock - quantity)) {
                return true; // 成功減少庫(kù)存
            }
            // 競(jìng)爭(zhēng)失敗,重試
        }
    }
    public int getStock(String productId) {
        AtomicInteger stock = inventory.get(productId);
        return stock != null ? stock.get() : 0;
    }
    public void increaseStock(String productId, int quantity) {
        AtomicInteger stock = inventory.computeIfAbsent(productId, k -> new AtomicInteger(0));
        stock.addAndGet(quantity);
    }
}

六、總結(jié)

Java 并發(fā)編程是一個(gè)復(fù)雜但強(qiáng)大的工具,通過(guò)合理使用并發(fā)工具和最佳實(shí)踐,我們可以構(gòu)建高并發(fā)、可伸縮的應(yīng)用。在實(shí)踐中,我們需要根據(jù)具體場(chǎng)景選擇合適的并發(fā)策略,避免常見(jiàn)的并發(fā)問(wèn)題,確保應(yīng)用的正確性和性能。

這其實(shí)可以更優(yōu)雅一點(diǎn)。

到此這篇關(guān)于Java并發(fā)編程最佳實(shí)踐之構(gòu)建高并發(fā)、可伸縮的應(yīng)用實(shí)例的文章就介紹到這了,更多相關(guān)Java構(gòu)建高并發(fā)、可伸縮內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用SpringDataJpa創(chuàng)建中間表

    使用SpringDataJpa創(chuàng)建中間表

    這篇文章主要介紹了使用SpringDataJpa創(chuàng)建中間表,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Mybatis如何開(kāi)啟控制臺(tái)打印sql語(yǔ)句

    Mybatis如何開(kāi)啟控制臺(tái)打印sql語(yǔ)句

    在SpringBoot與Mybatis整合開(kāi)發(fā)中,開(kāi)啟控制臺(tái)SQL語(yǔ)句打印是一個(gè)常見(jiàn)需求,有助于調(diào)試與性能優(yōu)化,方法一:在Mybatis配置文件mybatis-config.xml中添加設(shè)置;方法二:在SpringBoot配置文件application.yml或properties中
    2024-11-11
  • 關(guān)于Spring Cloud 本地屬性覆蓋的問(wèn)題

    關(guān)于Spring Cloud 本地屬性覆蓋的問(wèn)題

    這篇文章主要介紹了關(guān)于Spring Cloud 本地屬性覆蓋的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java8中的默認(rèn)方法(面試者必看)

    Java8中的默認(rèn)方法(面試者必看)

    這篇文章主要介紹了Java8中的默認(rèn)方法(面試者必看),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • RestTemplate get請(qǐng)求攜帶headers自動(dòng)拼接參數(shù)方式

    RestTemplate get請(qǐng)求攜帶headers自動(dòng)拼接參數(shù)方式

    這篇文章主要介紹了RestTemplate get請(qǐng)求攜帶headers自動(dòng)拼接參數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • java顯示當(dāng)前的系統(tǒng)時(shí)間

    java顯示當(dāng)前的系統(tǒng)時(shí)間

    這篇文章主要介紹了java如何顯示當(dāng)前的系統(tǒng)時(shí)間,代碼很簡(jiǎn)單,自己可以自定義顯示的系統(tǒng)時(shí)間的顏色和字體,需要的朋友可以參考下
    2015-10-10
  • SpringBoot淺析Redis訪問(wèn)操作使用

    SpringBoot淺析Redis訪問(wèn)操作使用

    Redis是一個(gè)速度非常快的非關(guān)系數(shù)據(jù)庫(kù)(Non-Relational?Database),它可以存儲(chǔ)鍵(Key)與多種不同類(lèi)型的值(Value)之間的映射(Mapping),可以將存儲(chǔ)在內(nèi)存的鍵值對(duì)數(shù)據(jù)持久化到硬盤(pán),可以使用復(fù)制特性來(lái)擴(kuò)展讀性能,還可以使用客戶(hù)端分片來(lái)擴(kuò)展寫(xiě)性能
    2022-11-11
  • Java連接Sql數(shù)據(jù)庫(kù)經(jīng)常用到的操作

    Java連接Sql數(shù)據(jù)庫(kù)經(jīng)常用到的操作

    這篇文章主要介紹了Java連接Sql數(shù)據(jù)庫(kù)經(jīng)常用到的操作的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • Netty學(xué)習(xí)教程之基礎(chǔ)使用篇

    Netty學(xué)習(xí)教程之基礎(chǔ)使用篇

    Netty是由JBOSS提供的一個(gè)Java開(kāi)源框架。Netty提供異步的、事件驅(qū)動(dòng)的網(wǎng)絡(luò)應(yīng)用程序框架和工具,用以快速開(kāi)發(fā)高性能、高可靠性的網(wǎng)絡(luò)服務(wù)器和客戶(hù)端程序。下面這篇文章主要給大家介紹了關(guān)于Netty基礎(chǔ)使用的相關(guān)資料,需要的朋友可以參考下。
    2017-05-05
  • java中l(wèi)ist和數(shù)組互相轉(zhuǎn)換的一些方法總結(jié)

    java中l(wèi)ist和數(shù)組互相轉(zhuǎn)換的一些方法總結(jié)

    在日常的Java開(kāi)發(fā)中經(jīng)常會(huì)遇到需要在數(shù)組和List之間進(jìn)行轉(zhuǎn)換的情況,這篇文章主要給大家介紹了關(guān)于java中l(wèi)ist和數(shù)組互相轉(zhuǎn)換的一些方法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-12-12

最新評(píng)論

黄平县| 泾源县| 阿瓦提县| 高安市| 德钦县| 永济市| 鹤峰县| 三河市| 清丰县| 南岸区| 精河县| 德安县| 西青区| 甘谷县| 墨玉县| 昔阳县| 阿克苏市| 新河县| 甘肃省| 桐庐县| 长海县| 潼关县| 镇沅| 大姚县| 贵阳市| 株洲市| 海门市| 普格县| 建阳市| 家居| 蚌埠市| 土默特右旗| 阜平县| 柳河县| 周口市| 鄂托克旗| 石家庄市| 庄河市| 都昌县| 大庆市| 云龙县|