1. 程式人生 > 實用技巧 >常見執行緒池 newScheduledThreadPool 定時執行任務的執行緒池 簡單介紹

常見執行緒池 newScheduledThreadPool 定時執行任務的執行緒池 簡單介紹

一 定時任務

package com.aaa.threaddemo;

import static java.util.concurrent.TimeUnit.NANOSECONDS;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; import javax.xml.crypto.Data; /* * 一 newScheduledThreadPool 是個啥? * 1 是一個執行緒池 * 2 可定時執行任務 * 3 核心執行緒數是固定的 * 4 非核心執行緒數 2147483647 * * public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); } public ScheduledThreadPoolExecutor(int corePoolSize) { super( corePoolSize, Integer.MAX_VALUE, 0, //非核心執行緒的生存時間是 0 馬上回收。 NANOSECONDS, new DelayedWorkQueue()); //一個優先順序的佇列 阻塞的佇列,因為它實現了BlockingQueue } DelayedWorkQueue() 優先順序佇列怎麼用的? 佇列一般都是先進先出的,但是在定時/延時任務中,我們需要的是延遲時間短的任務先執行。 為了解決這個問題,需要用到一種特殊的佇列 【優先順序佇列】 對插入的資料進行優先順序的排序,保證優先順序高的資料先執行。和往佇列中插入的順序無關。 沒能深入調查。。。。 二 提供了兩個方法可以用 schedule(command, delay, unit) schedule( task, 需要執行的任務 3, 間隔的時間 TimeUnit.SECONDS 時間單位 秒 分 時 。。。 ); scheduleAtFixedRate( command, initialDelay, 初次執行 間隔的時間 period, 再次執行的相隔時間 unit 時間的單位 ) 【注意!】 如果只有一次間隔時間,執行緒結束後關閉執行緒池即可。 schedule(command, delay, unit) 但是當有二次間隔時間,是不能將執行緒池 shutdown的! scheduleAtFixedRate(command, initialDelay, period, unit) *
*/ public class ScheduledThreadPoolDemo { public static void main(String[] args) { Integer integer = new Integer(0); int maxValue = integer.MAX_VALUE; System.out.println("[Integer.MAX_VALUE] = " + maxValue); SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //
驗證是否是在三秒後執行 System.out.println(df2.format(System.currentTimeMillis())); ExecutorService scheduledPool = Executors.newScheduledThreadPool(1); //建立定時的執行緒池 核心數量 2 ScheduledThreadDemo thread = new ScheduledThreadDemo(); Runnable task2 = new Runnable() { public void run() { System.out.println("開啟任務 task2"); } }; ((ScheduledExecutorService) scheduledPool).schedule(thread,3,TimeUnit.SECONDS); //1.對於thread 2. 延遲時間3後執行任務 3.單位TimeUnit.SECONDS 是 【秒】 三秒後執行 ((ScheduledExecutorService) scheduledPool).schedule(task2,5,TimeUnit.SECONDS); //延遲5秒後執行任務 scheduledPool.shutdown(); } } class ScheduledThreadDemo extends Thread{ @Override public void run() { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(df.format(System.currentTimeMillis())); System.out.println("我是執行緒1, 我在執行"); System.out.println("正在執行的執行緒名字" + Thread.currentThread().getName()); } }

看結果

二scheduleAtFixedRate ?

package com.aaa.threaddemo;

import static java.util.concurrent.TimeUnit.NANOSECONDS;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.xml.crypto.Data;

/*
 * 一 newScheduledThreadPool 是個啥?
 *         1 是一個執行緒池
 *         2 可定時執行任務
 *         3 核心執行緒數是固定的
 *         4 非核心執行緒數 2147483647
 * 
 * 
     public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
    }
    
    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(
        corePoolSize, 
        Integer.MAX_VALUE, 
        0,        //非核心執行緒的生存時間是 0 馬上回收。
        NANOSECONDS,
        new DelayedWorkQueue());  //一個優先順序的佇列      阻塞的佇列,因為它實現了BlockingQueue
        
    }    
    
   DelayedWorkQueue() 優先順序佇列怎麼用的?
        佇列一般都是先進先出的,但是在定時/延時任務中,我們需要的是延遲時間短的任務先執行。
        為了解決這個問題,需要用到一種特殊的佇列            
        【優先順序佇列】
            對插入的資料進行優先順序的排序,保證優先順序高的資料先執行。和往佇列中插入的順序無關。
            沒能深入調查。。。。
    
    
  二  提供了兩個方法可以用
  
          schedule(command, delay, unit)
          
          schedule(
          task,                  需要執行的任務
          3,                       間隔的時間
          TimeUnit.SECONDS    時間單位   秒 分 時 。。。
 );
      
        scheduleAtFixedRate(
        command,
        initialDelay,         初次執行 間隔的時間
        period,              再次執行的相隔時間
        unit                 時間的單位
)
    【注意!】
        如果只有一次間隔時間,執行緒結束後關閉執行緒池即可。      schedule(command, delay, unit)
        但是當有二次間隔時間,是不能將執行緒池 shutdown的!   scheduleAtFixedRate(command, initialDelay, period, unit)
         
       
 * 
 */
public class ScheduledThreadPoolDemo {
    public static void main(String[] args) {    
        SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  //驗證是否是在三秒後執行
        System.out.println(df2.format(System.currentTimeMillis()));  
        
        ExecutorService scheduledPool = Executors.newScheduledThreadPool(1);  //建立定時的執行緒池 核心數量 2
        ScheduledThreadDemo thread = new ScheduledThreadDemo();    
        
        Runnable task2 = new Runnable() {
            public void run() {
                System.out.println("開啟任務 task2");
            }
        };
        
        Runnable task3 = new Runnable() {
            public void run() {
                System.out.println("開啟任務 task3");
            }
        };
        
        ((ScheduledExecutorService) scheduledPool).schedule(thread,3,TimeUnit.SECONDS);        //1.對於thread  2. 延遲時間3後執行任務 3.單位TimeUnit.SECONDS 是 【秒】 三秒後執行
        ((ScheduledExecutorService) scheduledPool).schedule(task2,5,TimeUnit.SECONDS);        //延遲5秒後執行任務  
        
        ((ScheduledExecutorService) scheduledPool).scheduleAtFixedRate(task3, 8, 3, TimeUnit.SECONDS);  //對於task3 程式啟動 8秒後執行,中間間隔3秒執行一次。
        
//        scheduledPool.shutdown();
    }
}

class ScheduledThreadDemo extends Thread{
    @Override
    public void run() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
        System.out.println(df.format(System.currentTimeMillis()));  
        System.out.println("我是執行緒1, 我在執行");
        System.out.println("正在執行的執行緒名字" + Thread.currentThread().getName());
    }
    
}

檢視結果