1. 程式人生 > >Java多執行緒之執行緒排程詳解

Java多執行緒之執行緒排程詳解

排程的概念

給定時間結點,時間間隔,任務次數,然後自動執行任務

應用場景舉例

				1.日誌清理:每隔三個月,清理公司日誌檔案
				2.日誌備份:每個一週,備份公司檔案
				3.工資結算:每個月29號,考勤彙報,業務結算,計算工資

排程的實現方式:

  1. Timer+TimerTask
  2. ScheduledExecutor
  3. 開源工具包:Quartz,JcronTab

單執行緒排程

執行排程任務的個數為單個

Timer +TimerTask實現方式:

  1. Timer實現

Timer是一種工具,執行緒用其安排以後在後臺執行緒中執行的任務。可安排任務執行一次,或者定期重複執行。

主要方法摘要 在這裡插入圖片描述

  1. TimerTask 方法摘要 在這裡插入圖片描述

入門案例:

import java.util.Timer;
import java.util.TimerTask;

public class TimerTest {
public static void main(String[] args) {
	Timer timer = new Timer();
	//任務在多久以後執行
	long delay = 1000;//執行任務前的延遲時間,單位是毫秒。
	long period =1000;//執行各後續任務之間的時間間隔,單位是毫秒。 
	timer.scheduleAtFixedRate(new Task(), delay, period);
	//task - 所要安排的任務。
}
}
class Task extends TimerTask{

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println("正在工作");
	}
	
}
  1. TaskList 和TaskThread只有一個
  2. Timer物件接受任務和時間引數,將任務放到TimerList中,TimerList會按照,Task最初執行時間進行排序
  3. TimerThread在Timer在被建立時候會成為一個守護執行緒。
  4. TimerThread會找到最近排程的執行任務,記錄事件後休眠。
  5. 達到再次執行時間的時候,TimerThread重新執行
  6. 再一次記錄下一哥即將執行的任務後,休眠

缺點:同一時間,只會有一個任務被排程執行。上一個任務的執行會影響下一個任務的啟動時間。

多執行緒排程

執行排程任務的個數為單個

ScheduledExecutor的實現

  1. 每一被排程的任務,都可以從執行緒池中,安排一個執行緒來執行。任務併發執行,不受干擾。
  2. 會將放入的任務跟執行緒池匹配實現繫結

方法摘要 在這裡插入圖片描述 案例:


import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


public class ScheduledExecutorTest {
public static void main(String[] args) {
	//實現排程的執行緒池,建立一個有10個執行緒的執行緒池,而且可以實現排程。
	 ScheduledExecutorService service =Executors.newScheduledThreadPool(10);
	 //建立任務
	 ScheduleTask t1 = new ScheduleTask("小李");
	 ScheduleTask t2 = new ScheduleTask("小王");
	 long period =1;
	 long delay=1;
	 
	 //執行緒池繫結,執行緒會自動將任務給執行緒
	 service.scheduleAtFixedRate(t1, delay, period,TimeUnit.SECONDS);
	 service.scheduleAtFixedRate(t2, delay, period,TimeUnit.SECONDS);
	 /*
	  * command - 要執行的任務
		Delay - 首次執行的延遲時間
		period - 連續執行之間的週期
		unit - Delay 和 period 引數的時間單位 

	  * */
}
}

class ScheduleTask implements Runnable{
 private String Name ;
 
	public ScheduleTask(String name) {
	
	Name = name;
}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.println(Thread.currentThread().getName()+Name+"正在工作")
	}
	
}

缺點: 如果要精準定位某個時間點(例如:每個月29號,下午14:28分 12秒)去排程,就很複雜。