溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

異步加載緩存數(shù)據(jù)Java線程非阻塞優(yōu)化

發(fā)布時(shí)間:2024-11-08 18:27:39 來(lái)源:億速云 閱讀:80 作者:小樊 欄目:編程語(yǔ)言

在Java中,異步加載緩存數(shù)據(jù)并實(shí)現(xiàn)線程非阻塞優(yōu)化可以通過(guò)多種方式來(lái)實(shí)現(xiàn)。以下是一些常見(jiàn)的方法:

1. 使用CompletableFuture

CompletableFuture是Java 8引入的一個(gè)強(qiáng)大的異步編程工具,可以用來(lái)處理異步任務(wù)。

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class AsyncCacheLoader {
    private final Cache<String, String> cache = new ConcurrentHashMap<>();

    public CompletableFuture<String> loadAsync(String key) {
        return CompletableFuture.supplyAsync(() -> {
            // 模擬從數(shù)據(jù)庫(kù)或其他數(shù)據(jù)源加載數(shù)據(jù)
            return fetchDataFromDataSource(key);
        });
    }

    public String get(String key) {
        return cache.computeIfAbsent(key, this::loadAsync)
                     .thenApply(CompletableFuture::join)
                     .orTimeout(10, TimeUnit.SECONDS)
                     .exceptionally(ex -> {
                         System.err.println("Error loading data for key: " + key);
                         return null;
                     });
    }

    private String fetchDataFromDataSource(String key) {
        // 模擬從數(shù)據(jù)庫(kù)或其他數(shù)據(jù)源加載數(shù)據(jù)
        try {
            Thread.sleep(1000); // 模擬耗時(shí)操作
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return "Data for key: " + key;
    }

    public static void main(String[] args) {
        AsyncCacheLoader cacheLoader = new AsyncCacheLoader();
        cacheLoader.get("key1").thenAccept(System.out::println);
    }
}

2. 使用ExecutorService

ExecutorService是一個(gè)線程池,可以用來(lái)執(zhí)行異步任務(wù)。

import java.util.concurrent.*;

public class AsyncCacheLoader {
    private final Cache<String, String> cache = new ConcurrentHashMap<>();
    private final ExecutorService executorService = Executors.newFixedThreadPool(10);

    public Future<String> loadAsync(String key) {
        return executorService.submit(() -> {
            // 模擬從數(shù)據(jù)庫(kù)或其他數(shù)據(jù)源加載數(shù)據(jù)
            return fetchDataFromDataSource(key);
        });
    }

    public String get(String key) {
        return cache.computeIfAbsent(key, this::loadAsync)
                     .get();
    }

    private String fetchDataFromDataSource(String key) {
        // 模擬從數(shù)據(jù)庫(kù)或其他數(shù)據(jù)源加載數(shù)據(jù)
        try {
            Thread.sleep(1000); // 模擬耗時(shí)操作
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return "Data for key: " + key;
    }

    public static void main(String[] args) {
        AsyncCacheLoader cacheLoader = new AsyncCacheLoader();
        try {
            System.out.println(cacheLoader.get("key1"));
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        } finally {
            cacheLoader.executorService.shutdown();
        }
    }
}

3. 使用ConcurrentHashMapcomputeIfAbsent方法

ConcurrentHashMap提供了computeIfAbsent方法,可以在緩存未命中時(shí)異步加載數(shù)據(jù)。

import java.util.concurrent.*;

public class AsyncCacheLoader {
    private final Cache<String, String> cache = new ConcurrentHashMap<>();
    private final ExecutorService executorService = Executors.newFixedThreadPool(10);

    public String get(String key) {
        return cache.computeIfAbsent(key, key -> {
            // 模擬從數(shù)據(jù)庫(kù)或其他數(shù)據(jù)源加載數(shù)據(jù)
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                return fetchDataFromDataSource(key);
            }, executorService);

            future.thenApply(data -> {
                cache.put(key, data);
                return data;
            });

            return future;
        });
    }

    private String fetchDataFromDataSource(String key) {
        // 模擬從數(shù)據(jù)庫(kù)或其他數(shù)據(jù)源加載數(shù)據(jù)
        try {
            Thread.sleep(1000); // 模擬耗時(shí)操作
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return "Data for key: " + key;
    }

    public static void main(String[] args) {
        AsyncCacheLoader cacheLoader = new AsyncCacheLoader();
        System.out.println(cacheLoader.get("key1"));
    }
}

4. 使用ScheduledExecutorService進(jìn)行定時(shí)刷新

如果需要定期刷新緩存數(shù)據(jù),可以使用ScheduledExecutorService。

import java.util.concurrent.*;

public class AsyncCacheLoader {
    private final Cache<String, String> cache = new ConcurrentHashMap<>();
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    public AsyncCacheLoader() {
        scheduler.scheduleAtFixedRate(this::refreshCache, 0, 5, TimeUnit.SECONDS);
    }

    public String get(String key) {
        return cache.get(key);
    }

    private void refreshCache() {
        // 模擬從數(shù)據(jù)庫(kù)或其他數(shù)據(jù)源加載數(shù)據(jù)
        for (String key : cache.keySet()) {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                return fetchDataFromDataSource(key);
            }, executorService);

            future.thenApply(data -> {
                cache.put(key, data);
                return data;
            });
        }
    }

    private String fetchDataFromDataSource(String key) {
        // 模擬從數(shù)據(jù)庫(kù)或其他數(shù)據(jù)源加載數(shù)據(jù)
        try {
            Thread.sleep(1000); // 模擬耗時(shí)操作
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return "Data for key: " + key;
    }

    public static void main(String[] args) {
        AsyncCacheLoader cacheLoader = new AsyncCacheLoader();
        System.out.println(cacheLoader.get("key1"));
    }
}

通過(guò)這些方法,可以實(shí)現(xiàn)異步加載緩存數(shù)據(jù)并確保線程非阻塞,從而提高系統(tǒng)的性能和響應(yīng)速度。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI