1. 程式人生 > >定時器和多執行緒

定時器和多執行緒

定時器和多執行緒

1、任務簡介

本文分享的是杜老師《工程訓練》任務2.3中的普通任務,通過該任務我們可以初步學習Java中定時器與多執行緒的相關知識,該任務我是在5月完成的,但是一直未將該部分任務上傳,故今天對該部分任務的學習進行敘述,詳細的思路和程式碼在下文中進行分享。


2、基本任務和程式碼

(1)任務1

1)任務內容
完成一個java application應用程式,使用定時器程式設計,在實時顯示當前時間,每1秒時鐘內容更新一次。

2)任務程式碼
我首先需要了解java定時器的作用,在應用開發中,經常需要一些週期性的操作,比如每5分鐘執行某一操作等,對於這樣的操作最方便、高效的實現方式就是使用java.util.Timer工具類,即使用java定時器,其中Timer有兩個核心的屬性,一個是TaskQueue物件,用於儲存任務佇列,一個是TimerThread,用於執行佇列中的任務;

要執行一個定時任務,最基本的步驟如下:首先建立一個要執行的任務TimerTask,然後建立一個Timer例項,通過Timer提供的schedule()方法,將 TimerTask加入到定時器Timer中,同時設定執行的規則即可,當程式執行了Timer初始化程式碼後,Timer定時任務就會按照設定去執行;

對於Timer中的schedule()方法及其語句的詳解如下圖所示:
這裡寫圖片描述

對於系統當前時間的定義方法在任務1.3中已經學習過了,可以借鑑任務1.3的格式來定義當前的系統時間,在對Timer方法進行了簡單的學習之後,我準備使用Myeclipse編寫程式來實現任務所要求的功能,程式碼如下:

//每1S重新整理顯示當前系統時間
import java.text.SimpleDateFormat;//匯入java.text包下的SimpleDateFormat類
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
//import java.util.*;//匯入java.util包下的所有類
public class Timer1 {//類名
    public static void main(String[] args){//程式主函式
        Timer time=new Timer();//建立一個Timer類的例項
MyTask task=new MyTask();//建立一個MyTask類的例項 time.schedule(task, 0,1000);//指定無延遲的執行,並且重新整理時間為1S } } class MyTask extends TimerTask{//建立一個MyTask類繼承於父類TimerTask public void run(){//run方法,裡面包含需要執行的任務 SimpleDateFormat simpleDateFormat=null;//初始化當前時間 //獲取當前時間資訊,並定義其格式 SimpleDateFormat t=new SimpleDateFormat("yyyy-MM-dd"+" "+"HH:mm:ss"); String a=t.format(new Date());//將當前時間資訊賦給變數a System.out.println("當前系統時間為:"+a);//輸出當前時間資訊 } }

3)執行結果:
這裡寫圖片描述

(2)任務2

1)任務內容
完成一個java application應用程式,在應用程式主程序中新開一個執行緒,此執行緒進行死迴圈,每1秒被啟用一次,啟用時即在輸出顯示當前時間。

2)任務程式碼:
在對定時器的知識進行學習之後,我們需要學習java中多執行緒的知識,Java 給多執行緒程式設計提供了內建的支援,一條執行緒指程序中一個單一順序的控制流,一個程序中可以併發多個執行緒,每條執行緒並行執行不同的任務,用多執行緒只有一個目的,那就是更好的利用CPU的資源,而每一個執行緒都有自己的生命週期,如下圖所示:
這裡寫圖片描述
Java 提供了三種建立執行緒的方法:1、通過實現 Runnable 介面;2、通過繼承 Thread 類本身;3、通過 Callable 和 Future 建立執行緒;我本次編寫程式選擇使用繼承Thread 類建立執行緒,每隔1S啟用一次,並顯示當前的系統時間,程式程式碼如下:

import java.text.SimpleDateFormat;//匯入java.text包下的SimpleDateFormat類
import java.util.Date;//匯入java.util包下的Date類
public class Timer2 {//類名
    public static void main(String[] args) {//程式主函式
        Thread t=new Thread();//建立一個新的執行緒
        date d=new date();//建立一個date類物件
        d.start();//開啟執行緒
    }
}
class date extends Thread{//建立一個date類繼承於父類Thread
    public void run(){//run方法,裡面包含需要執行的任務
        while (true){//定義死迴圈
            try{//try程式碼塊,當發生異常時會轉到catch程式碼塊中
                Thread.sleep(1000);//死迴圈中的執行緒每隔一秒啟用一次
                SimpleDateFormat simpleDateFormat=null;//初始化當前時間
                //獲取當前時間資訊,並定義其格式
                SimpleDateFormat d=new SimpleDateFormat("yyyy-MM-dd"+"  "+"HH:mm:ss");
                String a=d.format(new Date());//將當前時間資訊賦給變數a
                System.out.println("當前系統時間為:"+a);//輸出當前時間資訊
            }
            catch(InterruptedException e){//當try程式碼塊有異常時轉到catch程式碼塊
            }
        }
    }
}

3)執行結果
這裡寫圖片描述

(3)任務3

1)任務內容
完成一個java application應用程式,此應用程式公共類有一個double型類屬性(變數)x,初始值為0;在應用程式主程序中新開兩個執行緒,這兩個執行緒都進行死迴圈;第1個執行緒每隔300ms啟用一次,令類屬性x自加1.0並輸出顯示;第2個執行緒每隔400ms啟用一次,令類屬性x自加0.1並輸出顯示。

2)任務程式碼
前一個步驟中只使用了一個執行緒來執行任務,而在本步驟中需要建立兩個執行緒來同時執行任務,故真正需要使用到多執行緒的知識,分別對兩個執行緒進行定時,並在每次啟用後對x進行輸出,並且在指定時間間隔後輸出一次x的值;

對於該程式中的兩個執行緒我需要分別通過Runnable介面來建立,並使它們在規定的啟用間隔後輪流對x進行加法操作,並在每次操作後都要輸出x的值,其中需要使用語句Thread a=new Thread(new AThread());來分別建立新的執行緒類,程式程式碼如下所示:

public class Timer3{//類名
   static double x=0; //定義一個浮點型變數並賦值
   public static void main(String[] args){//程式主函式
       Thread a=new Thread(new AThread());//建立一個新的執行緒的物件,這裡只能引用靜態的方法
       Thread b=new Thread(new BThread());//建立一個新的執行緒的物件,這裡只能引用靜態的方法
       System.out.println("初值:"+x);//輸出浮點型變數x的初值
       a.start();//開啟執行緒a
       b.start();//開啟執行緒b
       }
public static class AThread implements Runnable{//通過實現Runnable介面來建立執行緒類
    public void run(){//run方法,裡面包含需要執行的任務
        try{//try程式碼塊,當發生異常時會轉到catch程式碼塊中
            while(true){//定義死迴圈
                Thread.sleep(300);//死迴圈中的執行緒每300ms啟用一次
                x+=1;//x=x+1
                System.out.println("執行緒1:"+x);//在控制檯輸出x
                }
            }
        catch(InterruptedException e){}//當try程式碼塊有異常時轉到catch程式碼塊
        }
    }
public static class BThread implements Runnable{//通過實現Runnable介面來建立執行緒類
    public void run(){//run方法,裡面包含需要執行的任務
        try{//try程式碼塊,當發生異常時會轉到catch程式碼塊中
            while(true){//定義死迴圈
                Thread.sleep(400);//死迴圈中的執行緒每400ms啟用一次
                x+=0.1;//x=x+0.1
                System.out.println("執行緒2:"+x);//在控制檯輸出x
                }
            }
        catch(InterruptedException e){}//當try程式碼塊有異常時轉到catch程式碼塊
        }
    }
}

3)執行結果
這裡寫圖片描述

3、總結

本部落格簡單介紹了Java中定時器和多執行緒程式設計的一些例子,大家可以在普通任務的基礎上嘗試進行挑戰任務,特別是將普通任務3修改為挑戰任務1,對於本文程式中的不足之處懇請大家指正。