280 likes | 299 Views
Learn how to manage thread pools effectively in Java, covering topics like thread limits, handling capacity overloads, exceptions, and more.
E N D
國立交通大學資訊工程學系分散式系統實驗室 Distributed Computing Systems Lab Java Thread Pool實務與陷阱 葉秉哲 2008.08.23. http://william.cswiz.org
Agenda • Threads 數量上限 • 容量滿載的處理策略 • 異常處理 • 天有不測風雲 2.
參考資料 • Scott Oaks & Henry Wong (2004), Java Threads, 3rd edition, O’Reilly. • Brian Goetz et. al (2006), Java Concurrency in Practice, Addison-Wesley. 3.
Demo 1 Native thread 上限 (C/C++) 5.
Demo 2 VM thread 上限 (Java) 6.
Thread Object run( ) start( ) sleep( ) … wait( ) notify( ) notifyAll( ) … « interface »Runnable run( ) Java Concurrency Facilities Keyword: synchronized java.lang
Thread MyThread run( ) start( ) sleep( ) … run( ) Java Threads, 1st Way java.lang n main
others java.lang MyThread « interface »Runnable run( ) run( ) 1 1 n Java Threads, 2nd Way Thread main
Thread 容量滿載 • Win32 API • CreateThread() return NULL • Java • Throw java.lang.OutOfMemoryError 10.
java.util.concurrent « interface »Executor « interface »Runnable « utility »Executors execute( Runnable ) run( ) « factory » newFixedThreadPool( ) newCachedThreadPool( ) newScheduledThreadPool( ) … n 1 « instantiate » XXX « use » « use » MyWorker main 12.
Demo 3 固定容量的 Thread Pool 13.
newFixedThreadPool public class TestThreadPool { private static final int POOL_SIZE = 10; private static final int MAX_COUNT = 10000; public static void main(String[] args) { Executorpool = Executors.newFixedThreadPool(POOL_SIZE); for (int i = 0; i < MAX_COUNT; ++i) pool.execute( new ExecutorDemo(i) ); } } class ExecutorDemo implements Runnable { public ExecutorDemo(int sn) { /*…*/ } public void run() { /*…*/ } }
« utility »Executors « factory » newFixedThreadPool( ) newCachedThreadPool( ) newScheduledThreadPool( ) … Executors 懶人包 • FixedThreadPool • 固定數量 • 彈性不足 • CachedThreadPool • 自動伸縮 (0~Integer.MAX_VALUE) • 無法處理瞬間巨量 15.
Demo 4 兼顧並行性與系統負載的 Thread Pool 16.
ThreadPool – DIY! public class TestThreadPool { private static final int MAX_POOL_SIZE = 10; private static final int CORE_POOL_SIZE = 5 ; private static final long THREAD_KEEPALIVE_TIME = 60 ; private static final int QUEUE_SIZE = 3; //… public static void main(String[] args) { Executorpool = Executors.newThreadPoolExecutor( CORE_POOL_SIZE, MAX_POOL_SIZE, THREAD_KEEPALIVE_TIME, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(QUEUE_SIZE), new ThreadPoolExecutor.CallerRunsPolicy() ); /*…*/ } }
Demo 5 當 Thread Pool 遇見 exception… 19.
他抓得住我? public class TestThreadPool { //… public static void main(String[] args) { Executorpool = Executors.newFixedThreadPool(POOL_SIZE); for (int i = 0; i < MAX_COUNT; ++i) try { pool.execute( new ExecutorDemo(i) ); } catch (Throwable e) { /*…*/ } } } class ExecutorDemo implements Runnable { public ExecutorDemo(int sn) { /*…*/ } public void run() { throw new RuntimeException(); } }
Demo 6 除錯版:安裝自訂的 Thread.UncaughtExceptionHandler 21.
安裝自訂的 ThreadFactory public class TestThreadPool { //… public static void main(String[] args) { Executorpool = Executors.newThreadPoolExecutor( CORE_POOL_SIZE, MAX_POOL_SIZE, THREAD_KEEPALIVE_TIME, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(QUEUE_SIZE), new SafeThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy() ); /*…*/ } } class SafeThreadFactory implements ThreadFactory { /*下一頁*/ }
自訂 UncaughtExceptionHandler class SafeThreadFactory implements ThreadFactory { @Override public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setUncaughtExceptionHandler( new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException( Thread t, Throwable e) { //… } } ); return thread; } }
Demo 7 懶人版:不讓 thread 丟出 exception 24.
Thread 防呆策略 class ErrorProofThread implements Runnable { //… public void run() { try { /* main program logic here… */ } catch (Throwable ignore) { // you can do nothing here } } }
Heartbeat • Watchdog 27.