自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

線程池拒絕策略:優(yōu)雅處理過載請(qǐng)求

開發(fā)
當(dāng)線程池達(dá)到最大容量時(shí),會(huì)出現(xiàn)任務(wù)無法提交的情況,這時(shí)需要處理這種情況的機(jī)制稱為“拒絕策略”(Rejection Policy)。本文將詳細(xì)講述 Java 中的線程池拒絕策略,幫助讀者理解其原理和應(yīng)用場景。

什么是線程池拒絕策略?

線程池拒絕策略是指當(dāng)線程池中的任務(wù)數(shù)量達(dá)到上限時(shí),新提交的任務(wù)如何處理的一種策略。Java 提供了幾種內(nèi)置的拒絕策略,開發(fā)者也可以自定義策略。

內(nèi)置的拒絕策略

Java 提供了以下幾種內(nèi)置的拒絕策略:

  • AbortPolicy:默認(rèn)策略,直接拋出 RejectedExecutionException 異常,阻止系統(tǒng)正常運(yùn)行。
  • CallerRunsPolicy:由調(diào)用線程處理該任務(wù),既不拋棄任務(wù),也不拋出異常。
  • DiscardPolicy:直接丟棄任務(wù),不予處理。
  • DiscardOldestPolicy:丟棄最舊的任務(wù),然后嘗試重新提交被拒絕的任務(wù)。

下面,我們通過代碼示例來詳細(xì)講述這些策略的實(shí)現(xiàn)和應(yīng)用。

代碼示例

創(chuàng)建一個(gè)簡單的線程池:

import java.util.concurrent.*;

public class ThreadPoolExample {
    private static final int CORE_POOL_SIZE = 2;
    private static final int MAX_POOL_SIZE = 4;
    private static final long KEEP_ALIVE_TIME = 10L;

    public static void main(String[] args) {
        // 使用 ArrayBlockingQueue 作為任務(wù)隊(duì)列,容量為 2
        BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(2);

        // 創(chuàng)建線程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
            CORE_POOL_SIZE,
            MAX_POOL_SIZE,
            KEEP_ALIVE_TIME,
            TimeUnit.SECONDS,
            queue
        );

        // 提交任務(wù)
        for (int i = 0; i < 10; i++) {
            final int taskNumber = i + 1;
            executor.submit(() -> {
                try {
                    System.out.println("Executing task " + taskNumber);
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }

        // 關(guān)閉線程池
        executor.shutdown();
    }
}

使用 AbortPolicy:

import java.util.concurrent.*;

public class AbortPolicyExample {
    public static void main(String[] args) {
        BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(2);
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
            2, 4, 10L, TimeUnit.SECONDS, queue,
            new ThreadPoolExecutor.AbortPolicy() // 使用 AbortPolicy
        );

        for (int i = 0; i < 10; i++) {
            final int taskNumber = i + 1;
            try {
                executor.submit(() -> {
                    try {
                        System.out.println("Executing task " + taskNumber);
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                });
            } catch (RejectedExecutionException e) {
                System.err.println("Task " + taskNumber + " was rejected");
            }
        }

        executor.shutdown();
    }
}

使用 CallerRunsPolicy:

import java.util.concurrent.*;

public class CallerRunsPolicyExample {
    public static void main(String[] args) {
        BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(2);
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
            2, 4, 10L, TimeUnit.SECONDS, queue,
            new ThreadPoolExecutor.CallerRunsPolicy() // 使用 CallerRunsPolicy
        );

        for (int i = 0; i < 10; i++) {
            final int taskNumber = i + 1;
            executor.submit(() -> {
                System.out.println("Executing task " + taskNumber);
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }

        executor.shutdown();
    }
}

使用 DiscardPolicy:

import java.util.concurrent.*;

public class DiscardPolicyExample {
    public static void main(String[] args) {
        BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(2);
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
            2, 4, 10L, TimeUnit.SECONDS, queue,
            new ThreadPoolExecutor.DiscardPolicy() // 使用 DiscardPolicy
        );

        for (int i = 0; i < 10; i++) {
            final int taskNumber = i + 1;
            executor.submit(() -> {
                System.out.println("Executing task " + taskNumber);
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }

        executor.shutdown();
    }
}

使用 DiscardOldestPolicy:

import java.util.concurrent.*;

public class DiscardOldestPolicyExample {
    public static void main(String[] args) {
        BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(2);
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
            2, 4, 10L, TimeUnit.SECONDS, queue,
            new ThreadPoolExecutor.DiscardOldestPolicy() // 使用 DiscardOldestPolicy
        );

        for (int i = 0; i < 10; i++) {
            final int taskNumber = i + 1;
            executor.submit(() -> {
                System.out.println("Executing task " + taskNumber);
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }

        executor.shutdown();
    }
}

來點(diǎn)通俗易懂的

為了更好地理解這些拒絕策略,我們可以將其類比于生活中的場景:

  • AbortPolicy:就像餐廳已滿員,不再接待新客人,并告知客人“已經(jīng)客滿,請(qǐng)去別處”。
  • CallerRunsPolicy:就像餐廳忙不過來時(shí),老板自己上陣服務(wù)客人,保證所有客人都能被服務(wù)到。
  • DiscardPolicy:就像餐廳已滿員,直接不理會(huì)新來的客人,不告知任何信息。
  • DiscardOldestPolicy:就像餐廳已滿員,把最早來但還沒點(diǎn)菜的客人請(qǐng)走,以便接待新來的客人。

自定義拒絕策略

除了內(nèi)置的拒絕策略,開發(fā)者還可以根據(jù)實(shí)際需求自定義拒絕策略。例如,記錄日志、發(fā)送通知等。

import java.util.concurrent.*;

public class CustomRejectionPolicyExample {
    public static void main(String[] args) {
        BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(2);
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
            2, 4, 10L, TimeUnit.SECONDS, queue,
            new RejectedExecutionHandler() {
                @Override
                public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                    System.err.println("Task " + r.toString() + " was rejected");
                    // 這里可以添加更多處理邏輯,比如記錄日志、發(fā)送通知等
                }
            }
        );

        for (int i = 0; i < 10; i++) {
            final int taskNumber = i + 1;
            executor.submit(() -> {
                System.out.println("Executing task " + taskNumber);
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }

        executor.shutdown();
    }
}

結(jié)語

通過本文的介紹和代碼示例,相信大家對(duì) Java 線程池的拒絕策略有了更深入的理解。在實(shí)際開發(fā)中,選擇合適的拒絕策略能有效提升系統(tǒng)的穩(wěn)定性和用戶體驗(yàn)。

責(zé)任編輯:趙寧寧 來源: 源話編程
相關(guān)推薦

2020-11-25 11:33:47

Java線程技術(shù)

2020-07-08 12:05:55

Java線程池策略

2020-02-18 14:25:51

Java線程池拒絕策略

2022-03-14 07:32:06

線程池拒絕策略自定義

2009-07-20 17:49:07

JSF請(qǐng)求處理

2024-11-13 16:37:00

Java線程池

2024-11-11 17:27:45

2021-06-17 09:32:39

重復(fù)請(qǐng)求并發(fā)請(qǐng)求Java

2023-08-15 15:33:29

線程池線程數(shù)

2025-03-05 10:34:56

2024-01-08 09:09:40

線程池異常黑洞Futrue

2024-04-26 00:00:02

Java線程池策略

2025-02-24 00:00:10

.NET線程池模型

2025-04-28 00:55:00

2023-12-20 10:04:45

線程池Java

2024-09-30 08:54:10

2023-05-12 12:09:38

職責(zé)鏈模式客服

2009-07-24 10:57:41

ASP.NET ISAIIS6

2011-04-13 14:57:11

ASP.NET請(qǐng)求處理

2009-09-24 17:11:53

Hibernate處理
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)