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

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

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

一、引言

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

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

1. 線程安全

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

2. 并發(fā)工具類

基本工具

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

并發(fā)集合

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

線程池

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

三、最佳實踐

1. 線程池使用

合理配置線程池

// 好的做法
ThreadPoolExecutor executor = new ThreadPoolExecutor(
    corePoolSize,          // 核心線程數(shù)
    maximumPoolSize,       // 最大線程數(shù)
    keepAliveTime,         // 線程存活時間
    TimeUnit.SECONDS,      // 時間單位
    new LinkedBlockingQueue<>(queueCapacity), // 任務(wù)隊列
    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:適合簡單場景
  • ReentrantLock:適合復(fù)雜場景,支持公平鎖和非公平鎖
  • ReadWriteLock:適合讀多寫少的場景
  • StampedLock:JDK 8+ 提供,性能更好

鎖優(yōu)化

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

示例

// 好的做法
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ā)集合使用

選擇合適的集合

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

示例

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

4. 線程安全的單例模式

枚舉單例

// 最佳實踐
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 類

  • AtomicInteger:原子整數(shù)
  • AtomicLong:原子長整型
  • AtomicReference:原子引用
  • AtomicStampedReference:帶版本號的原子引用

示例

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

6. 并發(fā)工具

CountDownLatch

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

CyclicBarrier

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

Semaphore

// 控制并發(fā)訪問數(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. 死鎖

避免死鎖

  • 按固定順序獲取鎖
  • 使用超時機制
  • 使用 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. 活鎖

避免活鎖

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

3. 饑餓

避免饑餓

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

五、實戰(zhàn)案例

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

需求

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

實現(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; // 庫存不足
            }
            if (stock.compareAndSet(currentStock, currentStock - quantity)) {
                return true; // 成功減少庫存
            }
            // 競爭失敗,重試
        }
    }
    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ā)編程是一個復(fù)雜但強大的工具,通過合理使用并發(fā)工具和最佳實踐,我們可以構(gòu)建高并發(fā)、可伸縮的應(yīng)用。在實踐中,我們需要根據(jù)具體場景選擇合適的并發(fā)策略,避免常見的并發(fā)問題,確保應(yīng)用的正確性和性能。

這其實可以更優(yōu)雅一點。

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

相關(guān)文章

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

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

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

    Mybatis如何開啟控制臺打印sql語句

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

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

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

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

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

    RestTemplate get請求攜帶headers自動拼接參數(shù)方式

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

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

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

    SpringBoot淺析Redis訪問操作使用

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

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

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

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

    Netty是由JBOSS提供的一個Java開源框架。Netty提供異步的、事件驅(qū)動的網(wǎng)絡(luò)應(yīng)用程序框架和工具,用以快速開發(fā)高性能、高可靠性的網(wǎng)絡(luò)服務(wù)器和客戶端程序。下面這篇文章主要給大家介紹了關(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開發(fā)中經(jīng)常會遇到需要在數(shù)組和List之間進行轉(zhuǎn)換的情況,這篇文章主要給大家介紹了關(guān)于java中l(wèi)ist和數(shù)組互相轉(zhuǎn)換的一些方法,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-12-12

最新評論

阿克陶县| 故城县| 福州市| 茌平县| 宁陵县| 永安市| 高淳县| 衡水市| 邵阳县| 樟树市| 雅江县| 昆山市| 驻马店市| 商城县| 杭锦后旗| 通渭县| 都安| 阿尔山市| 贺州市| 荣成市| 化州市| 金塔县| 盐亭县| 鄂州市| 佛山市| 扬州市| 青铜峡市| 梁河县| 晋城| 调兵山市| 房产| 武强县| 建德市| 花垣县| 和平区| 黑河市| 新兴县| 聂荣县| 南阳市| 左权县| 三原县|