JAVAマルチスレッドFutureが非同期に戻り実現

4264 ワード

Future基本知識は紹介しないで、主に簡単な実現方式です。
1.スレッドを作成
FixedThreadPoolとCachedThreadPoolの特性比較
特性
Fixed ThreadPool
CachedThreadPool
再利用
FixedThreadPoolはCacheThreadPoolと同じぐらいで、reuseも使えますが、いつでも新しいスレッドを立てることはできません。
キャッシュ型の池では、まず池の中に以前に作られたスレッドがありますか?あったら、reuseです。ない場合は、新しいスレッドを作ってプールに参加します。
プールのサイズ
nThreadsを指定できます。固定数量
最大値Integer.MAX_VALE
キューサイズ
制限なし
制限なし
タイムアウト
IDLEがありません
デフォルトの60秒IDLE
使用シーン
したがって、FixedThreadPoolの多くは、いくつかの非常に安定しています。
大量の短いライフサイクルの非同期タスク
終了
自動的に破壊されません
なお、CachedThreadPoolを入れるスレッドは、終了を心配する必要はなく、TIMEOUTを超えて活動しないと自動的に終了します。
 
 
 
 
 
 
 
 
 
ベストな実践
FixedThreadPoolとCachedThreadPoolの両方は、高負荷への応用は特に友好的ではない。
CachedThreadPoolはFixedThreadPoolより危険が多いです。
高負荷、低遅延が要求される場合、上記の2つのスレッドを選択しない方がいいです。
  • タスクキューの無境界:メモリオーバーフローおよび高遅延
  • を引き起こす。
  • 長時間の運転は、結果として生じる。  CachedThreadPool スレッド作成上で暴走しました。
    どちらもあまり友好的ではないので、おすすめです。  ThreadPoolExecutor ,多くのパラメータが微細度の制御を可能にする。
  • は、タスクキューを境界のあるキュー
  • に設定する。
  • 適切な使用  RejectionHandler - カスタム  RejectionHandler またはJDKが提供するデフォルトのハンドル。
  • ジョブが完了する前にいくつかの動作を実行する必要がある場合、
     beforeExecute(Thread, Runnable)
     afterExecute(Runnable, Throwable)
  • を再ロードすることができる。
  • 重負荷ThreadFactory、スレッド定化需要があれば
  • 実行時に、スレッド池のサイズを動的に制御する
  •  
    共有スレッドを作成し、この例ではThreadPool Exectorスレッドを使用しています。
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;
    
    public class CommonThreadPoolExecutor {
    
        public static final ThreadPoolExecutor futureThreadPool; //       
    
        static {
    
    
            //            ,     
            final int PARTNER_COREPOOLSIZE = 40;
            //            
            final int PARTNER_MAXINUMPOOLSIZE = 200;
            //               
            final long PARTNER_KEEPALIVETIME = 0;
            //                  
            final TimeUnit PARTNER_UNIT = TimeUnit.SECONDS;
            //           ,       20
            final BlockingQueue PARTNER_WORKQUEUE = new ArrayBlockingQueue(20);
    
            //             :AbortPolicy     ;CallerRunsPolicy          ,        execute()  ;DiscardOldestPolicy       ,DiscardPolicy        
            final ThreadPoolExecutor.CallerRunsPolicy PARTNER_HANDLER = new ThreadPoolExecutor.CallerRunsPolicy();
            futureThreadPool = new ThreadPoolExecutor(PARTNER_COREPOOLSIZE, PARTNER_MAXINUMPOOLSIZE, PARTNER_KEEPALIVETIME, PARTNER_UNIT, PARTNER_WORKQUEUE, PARTNER_HANDLER);
        }
    }
     
    2.業務の実現
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.*;
    
    public class CommonService {
    
        public static void main(String[] args) {
    
            //           ,                  
            ThreadPoolExecutor executor = CommonThreadPoolExecutor.futureThreadPool;
    
            try {
                //                   ,             。
                CompletionService completionService = new ExecutorCompletionService(executor);
    
                Future future = null;
    
                //        
                List results = new ArrayList<>();
    
                //           
                String ids = "1,2,3";
    
                for (String pid : ids.split(",")) {
    
                    final String id = pid;
    
                    future = completionService.submit(new Callable() {
    
                        @Override
                        public Object call() {
                            //       
                            System.out.println(id);
                            //        
                            return new Object();
                        }
                    });
    
                    //       
                    results.add(future);
                }
                
                Object obj = null;
                for (Future fut : results) {
                    // fut.get()        
                    obj = (Object)fut.get();
                }
    
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
    }
    
     
    注:スレッドを使用すると、対応速度が大きくなりますが、サーバーの圧力が高すぎるのを避けるために、慎重に使用する必要があります。