ThreadPoolExecutor介紹


ThreadPoolExecutor的說明

ThreadPoolExecutor常見的操作主要有以下幾個方法:

  1. getPoolSize():返回線程池實際的線程數。
  2. getActiveCount():返回在執行者中正在執行任務的線程數。
  3. getCompletedTaskCount():返回執行者完成的任務數。
  4. submit(): 提交一個線程給線程執行者,如果執行者有空余線程,則直接執行;否則等待直到有空閑線程。這里調用sumbit后,並不會阻塞調用線程。調用者所在的線程和執行的線程並發運行。

下面要着重介紹兩個方法:

  1. shutdown(): 調用這個方法后,線程執行者在完成當前已經提交的所有任務后,結束運行。
    a. 在主線程中如果調用線程執行者的這個方法,並不會使線程執行者中已經submit的任務中斷(無論是待執行、執行中)
    b. 調用shutdown會通知執行者,后面提交的任務“不允許接受”,在shutdown后提交任務,會拋出RejectedExecutionException的異常信息。
  2. shutdownNow(): 調用這個方法后,立即停止執行者的運行。返回待執行的Task。
    a. 中斷所有正在執行的線程: 正在執行的線程會收到中斷信息。拋出InterruptedException
    b. 后面提交的任務“不允許接受”,在shutdownNow后再調用submit提交任務,會拋出RejectedExecutionException的異常信息。

code1:

public class ThreadPoolTest {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
        for (int i = 0; i < 3; i++) {
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(100);
                        System.out.println("sub thread classs");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        executor.shutdown();
        System.out.println("Main classs");
    }
}

結果:

Main classs
sub thread classs
sub thread classs
sub thread classs

說明:
調用executor.submit后,並不會阻塞主線程。主線程和提交到執行者中的線程並發執行。

code2:

public class ThreadPoolTest {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
        for (int i = 0; i < 3; i++) {
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(100);
                        System.out.println("sub thread classs");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        executor.shutdown();
        executor.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(100);
                    System.out.println("sub thread classs");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        System.out.println("Main classs");
    }
}

結果:

Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task 
java.util.concurrent.FutureTask@1c910477 rejected from java.util.concurrent.
ThreadPoolExecutor@74bc2f47[Shutting down, pool size = 3, active threads = 3, queued tasks = 0, completed tasks = 0]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2048)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:821)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1372)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:110)
at ThreadPoolTest.ThreadPoolTest.main(ThreadPoolTest.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
sub thread classs
sub thread classs
sub thread classs

說明:
調用executor.shutdown()后,如果再調用submit()方法,調用線程會拋出rejectedExecution,如果沒有try,cacth直接中斷
后續的操作。

code3:

public class ThreadPoolTest {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
        for (int i = 0; i < 3; i++) {
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(100);
                        System.out.println("sub thread classs");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        List<Runnable> list=executor.shutdownNow();
        System.out.println("list size:"+list.size());
        executor.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(100);
                    System.out.println("sub thread classs");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        System.out.println("Main classs");
    }
}

結果:

list size:0
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at ThreadPoolTest.ThreadPoolTest$1.run(ThreadPoolTest.java:16)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at ThreadPoolTest.ThreadPoolTest$1.run(ThreadPoolTest.java:16)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at ThreadPoolTest.ThreadPoolTest$1.run(ThreadPoolTest.java:16)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task 
java.util.concurrent.FutureTask@3a9d04dc rejected from java.util.concurrent.ThreadPoolExecutor@1aaa2594
[Shutting down, pool size = 2, active threads = 2, queued tasks = 0, completed tasks = 1]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2048)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:821)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1372)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:110)
at ThreadPoolTest.ThreadPoolTest.main(ThreadPoolTest.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

說明:
調用shutDownNow()后,直接中斷所有的線程。並且后面submit()task會拋出rejectedExecution。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM