天天看點

線程管理:守護線程的建立和運作

線程管理:守護線程的建立和運作

守護線程的建立和運作

java有一種特别的線程叫做守護線程。這種線程的優先級非常低,通常在程式裡沒有其他線程運作時才會執行它。當守護線程是程式裡唯一在運作的線程時,jvm會結束守護線程并終止程式。

根據這些特點,守護線程通常用于在同一程式裡給普通線程(也叫使用者線程)提供服務。它們通常無限循環的等待服務請求或執行線程任務。它們不能做重要的任務,因為我們不知道什麼時候會被配置設定到cpu時間片,并且隻要沒有其他線程在運作,它們可能随時被終止。java中最典型的這種類型代表就是垃圾回收器。

在這個指南中, 我們将學習如何建立一個守護線程,開發一個用2個線程的例子;我們的使用線程會寫事件到queue, 守護線程會清除queue裡10秒前建立的事件。

準備

指南中的例子是使用eclipse ide 來實作的。如果你使用eclipse 或者其他的ide,例如netbeans, 打開并建立一個新的java項目。

怎麼做呢…

按照這些步驟來實作下面的例子:

1.   建立 event 類. 這個類隻是用來儲存我們程式裡的工作的事件資訊。聲明2個屬性,一個是java. util.date 類型的 date 和另一個是string 類型的event 。并生成它們的讀值和寫值方法。

2.   建立 writertask 類并實作runnable接口。

1

public class writertask implements runnable {

3.   聲明queue,儲存事件并實作類的構造函數,初始化queue。

private deque<event> deque;

2

public writertask (deque<event> deque){

3

this.deque=deque;

4

}

4.   實作這個任務的 run() 方法 。 此方法有100個循環。在每個循環中我們會建立 一個event對象,并儲存到 queue裡, 然後休眠1秒。

@override

public void run() {

for (int i=1; i<100; i++) {

   event event=new event();

05

   event.setdate(new date());

06

   event.setevent(string.format("the thread %s has generated an   event",thread.currentthread().getid()));

07

   deque.addfirst(event);

08

   try {

09

      timeunit.seconds.sleep(1);

10

   } catch (interruptedexception e) {

11

      e.printstacktrace();

12

   }

13

14

5.   建立 cleanertask 類并一定擴充thread類。

public class cleanertask extends thread {

6.   聲明 queue,儲存事件并實作類的構造函數,初始化queue,在這個構造函數,用setdaemon() 方法讓此線程成為守護線程。

public cleanertask(deque<event> deque) {

this.deque = deque;

setdaemon(true);

7.   實作run()方法。它是無限循環來擷取目前日期并調用 clean() 方法.

while (true) {

   date date = new date();

   clean(date);

8.   實作 clean() 方法. 它擷取最後的事件,如果它在10秒前被建立,就删除它并檢視下一個事件。如果一個事件被删除,它會寫一個事件資訊和queue的新的大小,為了讓你看到變化過程。

private void clean(date date) {

  long difference;

  boolean delete;

  if (deque.size()==0) {

    return;

  }

  delete=false;

  do {

    event e = deque.getlast();

    difference = date.gettime() - e.getdate().gettime();

    if (difference > 10000) {

     system.out.printf("cleaner: %s\n",e.getevent()); deque.removelast();

     delete=true;

    }

15

  } while (difference > 10000);

16

  if (delete){

17

   system.out.printf("cleaner: size of the queue: %d\n",deque. size());

18

19

9.   現在實作主類。 建立一個類名為 main 和 main() 方法。

public class main {

public static void main(string[] args) {

10. 建立使用 deque 類的queue 來儲存事件。

deque<event> deque=new arraydeque<event>();

11. 建立 和開始3個 writertask 線程和一個 cleanertask.

writertask writer=new writertask(deque);

for (int i=0; i<3; i++){

thread thread=new thread(writer);

thread.start();

cleanertask cleaner=new cleanertask(deque);

cleaner.start();

12. 運作程式檢視結果。

它是怎麼工作的…

如果分析這個程式的輸出,你可以發現queue可以一直增加直到它有30個事件,然後它的大小會在27-30之間直到運作結束。

程式開始時有3個 writertask 線程。每個線程寫一個事件然後休眠1秒。10秒之後,我們有30個事件在queue裡。在這10秒内,當3個 writertask 線程休眠時, cleanertasks已經開始運作,但是它沒有删除任何事件,因為所有事件都才生成不到10秒。在剩下的運作裡,cleanertask 每秒删除3個事件, 然而3個 writertask 線程會另寫3個,是以queue的大小在27-30之間。

你可以修改 writertask 線程的休眠時間。如果你使用一個較小的值,你會發現cleanertask 被配置設定到 cpu 時間片會更少,由于 cleanertask 沒有删除任何事件,是以queue大小會一直增加。

更多…

隻能在start() 方法之前可以調用 setdaemon() 方法。一旦線程運作了,就不能修改守護狀态。

可以使用 isdaemon() 方法來檢查線程是否是守護線程(方法傳回 true) 或者是使用者線程 (方法傳回 false)。

特别說明:尊重作者的勞動成果,轉載請注明出處哦~~~http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt204