Java学習ノート(スレッドプールの簡単な使用)


スレッドプールの概念
スレッドプールは、複数のスレッドを格納するコンテナであり、スレッドを繰り返し使用することができ、スレッドオブジェクトを頻繁に作成する操作を省くことができ、スレッドを繰り返し作成する必要がなく、リソースを消費しすぎます.
スレッドプールの使用
スレッド・プールの合理的な利用は、次の3つのメリットをもたらします.
  • リソース消費量を削減します.スレッドの作成と破棄の回数を減らし、各作業スレッドを再利用し、複数のタスクを実行できます.
  • は応答速度を向上させる.タスクが到着すると、スレッドが作成されるまでタスクを必要とせずにすぐに実行できます.
  • スレッドの管理性が向上します.システムの耐性に応じて、スレッドプール内のワークラインスレッドの数を調整し、メモリの消費が多すぎるため、サーバを疲れさせないようにすることができます(スレッドごとに約1 MBのメモリが必要で、スレッドが多ければ多いほど、メモリの消費量が大きくなり、最後にハングアップします).
  • java.util.concurrent.Executorsスレッドファクトリクラスには、いくつかの静的ファクトリが提供され、一般的なスレッドプールが生成されます.スレッドプールオブジェクトを作成するには、Executorsエンジニアリングクラスを使用することを推奨します.
    Executorsクラスでスレッドプールを作成する方法は次のとおりです.
  • public static ExecutorService newFixedThreadPool(int nThreads):スレッドプールオブジェクトを返します.(作成されたのは境界線付きプール、つまりプール内のスレッド数で最大数を指定できます)
  • スレッドプールExecutorServiceオブジェクトを取得しました.では、どのように使用しますか.ここでは、スレッドプールオブジェクトを使用する方法を定義します.
  • public Future> submit(Runnable task):スレッドプール内のスレッドオブジェクトを取得し、実行します.
    Futureインタフェース:スレッドタスクの実行後に発生した結果を記録します.

  • スレッドプール内のスレッドオブジェクトを使用するには:
  • スレッドプールオブジェクトを作成します.
  • Runnableインタフェースサブクラスオブジェクトを作成します.(task)
  • Runnableインタフェースサブクラスオブジェクトをコミットします.(take task)
  • スレッドプールを閉じます(一般的にはしません).

  • Runnable実装クラスコード:
    public class MyRunnable implements Runnable {
         
        @Override
        public void run() {
         
            System.out.println("      ");
            try {
         
                Thread.sleep(2000);
            } catch (InterruptedException e) {
         
                e.printStackTrace();
            }
            System.out.println("    : " + Thread.currentThread().getName());
            System.out.println("    ,   ,        ");
        }
    }
    
    public class ThreadPoolDemo {
         
        public static void main(String[] args) {
         
            //        
            ExecutorService service = Executors.newFixedThreadPool(2);//  2     
            //   Runnable    
            MyRunnable r = new MyRunnable();
    
            //           
            // Thread t = new Thread(r);
            // t.start(); --->   MyRunnable  run()
    
            //            ,    MyRunnable  run()
            service.submit(r);
            //         ,  MyRunnable  run()
            service.submit(r);
            service.submit(r);
            //   :submit       ,      ,              。
            //                 
            //      
            //service.shutdown();
        }
    }
    

    Callableテストコード:
  • Future submit(Callable task):スレッドプール内のスレッドオブジェクトを取得し、実行する.Future:計算の結果を表します.
  • V get():計算が完了した結果を取得します.
  • public class ThreadPoolDemo2 {
         
        public static void main(String[] args) throws Exception {
         
            //        
          ExecutorService service = Executors.newFixedThreadPool(2);//  2     
    
            //   Runnable    
            Callable<Double> c = new Callable<Double>() {
         
                @Override
                public Double call() throws Exception {
         
                    return Math.random();
                }
            };
    
            //            ,    Callable  call()
            Future<Double> f1 = service.submit(c);
            // Futur   get()       
            System.out.println(f1.get());
    
            Future<Double> f2 = service.submit(c);
            System.out.println(f2.get());
    
            Future<Double> f3 = service.submit(c);
            System.out.println(f3.get());
        }
    }
    

    スレッドプールの練習
    public class Demo04 {
         
        public static void main(String[] args) throws ExecutionException, InterruptedException {
         
            ExecutorService pool = Executors.newFixedThreadPool(3);
    
            SumCallable sc = new SumCallable(100);
            Future<Integer> fu = pool.submit(sc);
            Integer integer = fu.get();
            System.out.println("  : " + integer);
            
            SumCallable sc2 = new SumCallable(200);
            Future<Integer> fu2 = pool.submit(sc2);
            Integer integer2 = fu2.get();
            System.out.println("  : " + integer2);
    
            pool.shutdown();
        }
    }
    
    public class SumCallable implements Callable<Integer> {
         
        private int n;
    
        public SumCallable(int n) {
         
            this.n = n;
        }
    
        @Override
        public Integer call() throws Exception {
         
            //  1-n  ?
            int sum = 0;
            for (int i = 1; i <= n; i++) {
         
                sum += i;
            }
            return sum;
        }
    }