Heim > Java > javaLernprogramm > Hauptteil

Wie implementiert man die Ablehnungsrichtlinie von Java ThreadPoolExecutor?

WBOY
Freigeben: 2023-05-08 15:34:08
nach vorne
776 Leute haben es durchsucht

    Grundprinzip des Thread-Pools

    Das Prinzip des Thread-Pools lautet wie folgt:

    Wie implementiert man die Ablehnungsrichtlinie von Java ThreadPoolExecutor?

    Erklärung:

    • Wenn die Anzahl der aktuell ausgeführten Threads geringer als corePoolSize ist, erstellen Sie einen neuen Thread zur Ausführung die Aufgabe.

    • Wenn die laufenden Threads gleich oder größer als corePoolSize sind, wird die Aufgabe zur Warteschlange hinzugefügt.

    • Wenn die Aufgabenwarteschlange voll ist, wird im Nicht-CorePool ein neuer Thread erstellt, um die Aufgabe zu verarbeiten.

    • Das Erstellen eines neuen Threads führt dazu, dass die aktuell ausgeführten Threads die maximale Poolgröße überschreiten, die Aufgabe wird abgelehnt und die Methode RejectedExecutionHandler.rejectedExecution() wird aufgerufen.

    Thread-Pool-Ablehnungsstrategie

    Der Thread-Pool bietet uns vier Ablehnungsstrategien: CallerRunsPolicy, AbortPolicy, DiscardPolicy, DiscardOldestPolicy

    AbortPolicy

    Die Standard-Ablehnungsstrategie in ThreadPoolExecutor besteht darin, dass AbortPolicy direkt eine Ausnahme auslöst, die spezifische Implementierung As

    public static class AbortPolicy implements RejectedExecutionHandler {
        public AbortPolicy() { }
        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +
                                                 " rejected from " +
                                                 e.toString());
        }
    }
    Nach dem Login kopieren

    erklärt: Diese Strategie ist sehr einfach und grob. Sie löst direkt eine RejectedExecutionException-Ausnahme aus und führt keine nachfolgenden Aufgaben aus.

    Beispielbeschreibung:

    public class ThreadPoolTest
    {
        public static void main(String[] args)
        {
            ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                    2,
                    5,
                    10,
                    TimeUnit.MICROSECONDS,
                    new LinkedBlockingDeque<>(1),
                    new ThreadPoolExecutor.AbortPolicy());
            
            //异步执行
            for(int i=0; i<10;i++)
            {
              System.out.println("添加第"+i+"个任务");
              threadPoolExecutor.execute(new TestThread("线程"+i));
            }        
        }
    }
    
    public class TestThread implements Runnable
    {
        private String name;
        public TestThread(String name){
            this.name=name;
        }
        
        @Override
        public void run()
        {
            try
            {
                Thread.sleep(1000);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            System.out.println("thread name:"+Thread.currentThread().getName()+",执行:"+name);
        }
    }
    Nach dem Login kopieren

    Ausführungsergebnis:

    Ausnahme im Thread „main“ java.util.concurrent.RejectedExecutionException: Aufgabe com.skywares.fw.juc.thread.TestThread@55f96302 von java.util.concurrent abgelehnt. ThreadPoolExecutor@3d4eac69[Wird ausgeführt, Poolgröße = 5, aktive Threads = 5, Aufgaben in der Warteschlange = 1, abgeschlossene Aufgaben = 0]
    bei java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2047)
    bei java. util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:823)
    bei java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1369)
    bei com.skywares.fw.juc.thread.ThreadPoolTest.main(ThreadPoolTest. java:26)
    Thread-Name: Pool-1-Thread-5, Ausführung: Thread 5
    Thread-Name: Pool-1-Thread-2, Ausführung: Thread 1
    Thread-Name: Pool-1-Thread-4, Ausführung: Thread 4
    Thread-Name: Pool-1-Thread-3, Ausführung: Thread 3
    Thread-Name: Pool-1-Thread-1, Ausführung: Thread 0
    Thread-Name: Pool-1-Thread-5, Ausführung: Thread 2

    Aus den Ausführungsergebnissen wissen wir, dass bei Verwendung der AbortPolicy-Strategie direkt bei der Ausführung der Aufgabe ein Fehler an die siebte Aufgabe gemeldet wird, was dazu führt, dass die nachfolgende Geschäftslogik nicht ausgeführt wird.

    CallerRunsPolicy

    CallerRunsPolicy verwendet den oberen Thread, der die Ausführungsfunktion aufruft, um die abgelehnte Aufgabe auszuführen, nachdem die Aufgabe abgelehnt wurde.

    Verwandte Beispiele

    public class ThreadPoolTest
    {
        public static void main(String[] args)
        {
            ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                    2,
                    5,
                    10,
                    TimeUnit.MICROSECONDS,
                    new LinkedBlockingDeque<>(1),
                    new ThreadPoolExecutor.CallerRunsPolicy());
            
            //异步执行
            for(int i=0; i<10;i++)
            {
              System.out.println("添加第"+i+"个任务");
              threadPoolExecutor.execute(new TestThread("线程"+i));
            }
        }
    }
    Nach dem Login kopieren

    Ausführungsergebnisse:

    0. Aufgabe hinzufügen
    1. Aufgabe hinzufügen
    2. Aufgabe hinzufügen
    3. Aufgabe hinzufügen
    4. Aufgabe hinzufügen
    5. Aufgabe hinzufügen
    Die 6. Aufgabe hinzufügen
    Thread-Name: main, Ausführung: Thread 6
    Thread-Name: Pool-1-Thread-3, Ausführung: Thread 3
    Thread-Name: Pool-1-Thread-1, Ausführung: Thread 0
    Thread-Name: Pool-1-Thread-4, Ausführung: Thread 4
    Thread-Name: Pool-1-Thread-2, Ausführung: Thread 1
    Thread-Name: Pool-1-Thread-5, Ausführung: Thread 5
    Fügen Sie die 7. Aufgabe hinzu
    Fügen Sie die 8. Aufgabe hinzu
    Thread-Name: main, Ausführung: Thread 8
    Thread-Name: Pool-1-Thread-1, Ausführung: Thread 7
    Thread-Name: Pool-1-Thread-3, Ausführung: Thread 2
    Fügen Sie die 9. Aufgabe hinzu
    Thread-Name: Pool-1-Thread-1, Ausführung: Thread 9

    Aus den Ausführungsergebnissen können wir erkennen, dass diese Aufgabe aufgrund der Thread-Pool-Ablehnungsrichtlinie ausgeführt wird, wenn die 7. Aufgabe ausgeführt wird. Der Hauptthread wird ausgeführt, und wenn der Thread-Pool frei ist, wird er weiterhin ausgeführt andere Aufgaben ausführen. Diese Strategie kann also den Hauptthread blockieren.

    DiscardPolicy

    Diese Ablehnungsrichtlinie ist relativ einfach. Vom Thread-Pool abgelehnte Aufgaben werden direkt verworfen, ohne Ausnahmen auszulösen oder auszuführen

    dealStock-Erfolg aufrufen

    goodsId: Mobiltelefon

    Thread-Name: Pool-1-Thread-1, Ausführung: Thread 0

    Thread-Name: Pool-1-Thread-4, Ausführung: Thread 4

    Thread-Name: Pool-1- Thread-5, Ausführung: Thread 5

    Thread-Name: Pool-1-Thread-3, Ausführung: Thread 3
    Thread-Name: Pool-1-Thread-2, Ausführung: Thread 1

    Thread-Name: Pool-1-Thread- 1. Ausführung: Thread 2


    Den Ausführungsergebnissen nach zu urteilen, wurden nur 6 Aufgaben ausgeführt und andere Aufgaben wurden abgebrochen.

    DiscardOldestPolicy

    DiscardOldestPolicy Wenn eine Aufgabe das Hinzufügen ablehnt, wird die erste zur Aufgabenwarteschlange hinzugefügte Aufgabe verworfen und die neue Aufgabe hinzugefügt.

    Example Beschreibung -1-Thread-2, Ausführung: Thread 3

    Thread-Name: Pool-1-Thread-1, Ausführung: Thread 0

    Thread-Name: Pool-1-Thread-1, Ausführung: Thread 2

    Thread-Name: Pool-1 -thread-2, Ausführung: Thread 1

    自定义拒绝策略

    当线程池提供的拒绝策略无法满足要求时,我们可以采用自定义的拒绝策略,只需要实现RejectedExecutionHandler接口即可

    public class CustRejectedExecutionHandler implements RejectedExecutionHandler
    {
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor)
        {
            new Thread(r,"线程:"+new Random().nextInt(10)).start();
        }
    }
    
      ThreadPoolExecutor threadPoolExecutor  = new ThreadPoolExecutor(
                    1,
                    2,
                    10,
                    TimeUnit.MICROSECONDS,
                    new LinkedBlockingDeque<>(2),
                    new CustRejectedExecutionHandler());
    Nach dem Login kopieren

    执行结果:

    thread name:客户线程:6,执行:线程5
    thread name:pool-1-thread-1,执行:线程0
    thread name:客户线程:8,执行:线程4
    thread name:pool-1-thread-2,执行:线程3
    thread name:pool-1-thread-1,执行:线程1
    thread name:pool-1-thread-2,执行:线程2

    从执行的结果来看,被拒绝的任务都在客户的新线程中执行。

    小结

    • AbortPolicy:直接抛出异常,后续的任务不会执行

    • CallerRunsPolicy:子任务执行的时间过长,可能会阻塞主线程。

    • DiscardPolicy:不抛异常,任务直接丢弃

    • DiscardOldestPolicy;丢弃最先加入队列的任务

    Das obige ist der detaillierte Inhalt vonWie implementiert man die Ablehnungsrichtlinie von Java ThreadPoolExecutor?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Verwandte Etiketten:
    Quelle:yisu.com
    Erklärung dieser Website
    Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
    Beliebte Tutorials
    Mehr>
    Neueste Downloads
    Mehr>
    Web-Effekte
    Quellcode der Website
    Website-Materialien
    Frontend-Vorlage
    Über uns Haftungsausschluss Sitemap
    Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!