ScheduledExecutorServiceは、タイミングおよび周期的なタスク実行をサポートする定長スレッドプールです.

6818 ワード

ScheduledExecutorServiceの主な役割は、タイミングタスクとスレッドプール機能を組み合わせて使用できることです.
スレッドプールに基づいて設計されたタイミングタスククラスであるため、各スケジューリングタスクはスレッドプール内のスレッドに割り当てられて実行されます.すなわち、タスクは同時実行であり、互いに影響しません.
スケジューリング・タスクが来た場合にのみ、ScheduledExecutorServiceはスレッドを実際に起動し、残りの時間はタスクをポーリングした状態であることに注意してください.

ScheduledExecutorServiceスレッドプールを作成するには、次の2つの方法があります。


1つ目はExecutorsで作成


Executorsはファクトリモードを利用して4つのスレッドプールの実装方法を提供していますが、Executorsを使用してスレッドプールを作成するとこのパラメータが入力されずデフォルト値が使用されるため、このパラメータを無視することがよくあります.また、デフォルトで使用されるパラメータはリソースの浪費を引き起こし、望ましくありません.
ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();

ScheduledExecutorService mScheduledExecutorService = Executors.newScheduledThreadPool(num);

numはスレッドプールでnum個のスレッドを同時に実行できるという意味ですが、スレッドプールでは永遠にこの3つのスレッドであるわけではありません.ただ、同時に存在できるスレッド数という意味で、あるスレッドの実行が終了すると、新しいスレッドが入ってきます.
 

第2の方法もアリコード規範が推奨している。

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1,
 1,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue());

 ScheduledExecutorService newScheduledThreadPool =
 Executors.newScheduledThreadPool(4,threadPoolExecutor.getThreadFactory());
//org.apache.commons.lang3.concurrent.BasicThreadFactory
    ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
        new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build());

 ScheduledExecutorService falseexecutorService  = new ScheduledThreadPoolExecutor(num);

daemon(true)はスレッドを守るという意味です
Javaにはユーザスレッド(User Thread)、デーモンスレッド(Daemon Thread)の2種類がある.
デーモンスレッドとは、プログラムの実行時にバックグラウンドで汎用サービスを提供するスレッドであり、例えばゴミ回収スレッドは非常に適任なデーモンであり、このようなスレッドはプログラムの不可欠な部分ではない.したがって、すべての非デーモンスレッドが終了すると、プログラムは終了し、プロセス内のすべてのデーモンスレッドを殺すことになります.逆に言えば、非デーモンスレッドがまだ実行されている限り、プログラムは終了しません.
ユーザー・スレッドとデーモン・スレッドの違いはほとんどありません.唯一の違いは、仮想マシンの離脱です.ユーザー・スレッドがすべて実行を終了した場合、デーモン・スレッドだけが存在し、仮想マシンも終了します.被守護者がいなければ,守護スレッドも仕事ができず,プログラムを実行し続ける必要もないからである.
スレッドをデーモンスレッドに変換することは、ThreadオブジェクトのsetDaemon(true)メソッドを呼び出すことによって実現することができる.デーモンスレッドを使用する場合は、次の点に注意してください.
        (1) thread.setDaemon(true)はthread.start()の前に設定しないと、IllegalThreadStateException異常が飛び出します.実行中の通常のスレッドをデーモンスレッドに設定することはできません. 
(2)Daemonスレッドで生成された新しいスレッドもDaemonである.
(3)デーモン・スレッドは、いつでも1つの操作の間で中断されるため、ファイル、データベースなどの固有のリソースにアクセスしないでください.

ScheduledExecutorServiceの方法


      falseexecutorService.scheduleWithFixedDelay(command, initialDelay, delay, unit)       falseexecutorService.scheduleAtFixedRate(command, initialDelay, period, unit)        falseexecutorService.schedule(command, delay, unit)
  • パラメータcommandメソッド実行体
  • パラメータinitialDelayが初めて実行する遅延時間
  • パラメータdelayタイミング実行間隔時間
  • パラメータunit単位
  •         // TimeUnit.NANOSECONDS  
            // TimeUnit.MICROSECONDS  
            // TimeUnit.MILLISECONDS    
            // TimeUnit.SECONDS  
            // TimeUnit.MINUTES  
            // TimeUnit.HOURS  
            // TimeUnit.DAYS   

  • メソッドscheduleAtFixedRateループタスク


    scheduleAtFixedRateサイクルタスクは厳格に5秒ごとに開始する.sleep(3000); ただし、前のスレッドへの影響複数のスレッドが次のスレッドの実行に影響しない場合-->以上のタスクの開始時間+遅延時間=次のタスクの開始時間です.
     executorService.scheduleAtFixedRate(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("run {{"+Thread.currentThread().getName()+"}}> "
                            + System.currentTimeMillis()/1000);
                       try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }        
                   
                }, 1, 5,  //TimeUnit.MILLISECONDS  
                     TimeUnit.SECONDS);

    出力結果:
    run {{pool-1-thread-1}}> 1551258899
    run {{pool-1-thread-1}}> 1551258904
    run {{pool-1-thread-2}}> 1551258909

     

    メソッドscheduleWithFixedDelay遅延サイクルタスク


    scheduleWithFixedDelayループタスクは厳格に1秒ごとに開始され、sleep(3000)はタスクの開始に影響を与える以上のタスクの終了時間+遅延時間=次のタスクの開始時間である.
       executorService.scheduleWithFixedDelay(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("run {{"+Thread.currentThread().getName()+"}}> "
                         System.currentTimeMillis()/1000);
                       try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }        
                   
                }, 0, 5,  //TimeUnit.MILLISECONDS  
                     TimeUnit.SECONDS);

    出力結果:
    run {{pool-1-thread-1}}> 1551259165
    run {{pool-1-thread-1}}> 1551259173
    run {{pool-1-thread-2}}> 1551259181
    run {{pool-1-thread-1}}> 1551259189
    run {{pool-1-thread-1}}> 1551259197

     

    メソッドschedule遅延タスク


    scheduleは遅延タスクで1回のみ実行されます
            executorService.schedule((new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("run  >>>> "+ System.currentTimeMillis());
                    }
                }), 3, TimeUnit.MILLISECONDS);

    実行結果:
    run  >>>> 1551259382734