Java7并发编程实战(一) 守护线程的创建和运行

Java里有一种特殊的线程叫做守护(Daemon)线程,这种线程的优先级很低,通常来说,当一个应用程序里面没有其他线程运行的时候,守护线程才运行,当线程是程序中唯一运行的线程时,守护线程执行结束后,JVM也就结束了这个程序。因此,守护线程通常被用来作为同一程序中普通线程的服务提供者,通常是无线循环的,以等待服务请求或者线程任务。

 

  代码实现

  1:创建Event类,声明两个私有属性

   

package com.packtpub.java7.concurrency.chapter1.recipe7.event;

import java.util.Date;

/**
 * Class that stores event's information 
 *
 */
public class Event {

    /**
     * Date of the event
     */
    private Date date;
    
    /**
     * Message of the event
     */
    private String event;
    
    /**
     * Reads the Date of the event
     * @return the Date of the event
     */
    public Date getDate() {
        return date;
    }
    
    /**
     * Writes the Date of the event
     * @param date the date of the event
     */
    public void setDate(Date date) {
        this.date = date;
    }
    
    /**
     * Reads the message of the event
     * @return the message of the event
     */
    public String getEvent() {
        return event;
    }
    
    /**
     * Writes the message of the event
     * @param event the message of the event
     */
    public void setEvent(String event) {
        this.event = event;
    }
}
View Code

  2:创建WirterTask类,实现Runnable接口,声明一个存放Event对象的队列,并实现一个带参数的构造器,初始化这个队列,实现线程的run()方法,执行循环100次,每次循环中都会创建一个新的Event对象,并放入队列中,然后休眠1秒钟

package com.packtpub.java7.concurrency.chapter1.recipe7.task;

import java.util.Date;
import java.util.Deque;
import java.util.concurrent.TimeUnit;

import com.packtpub.java7.concurrency.chapter1.recipe7.event.Event;

/**
 * Runnable class that generates and event every second
 *
 */
public class WriterTask implements Runnable {

    /**
     * Data structure to stores the events
     */
    Deque<Event> deque;
    
    /**
     * Constructor of the class
     * @param deque data structure that stores the event
     */
    public WriterTask (Deque<Event> deque){
        this.deque=deque;
    }
    
    /**
     * Main class of the Runnable
     */
    @Override
    public void run() {
        
        // Writes 100 events
        for (int i=1; i<100; i++) {
            // Creates and initializes the Event objects 
            Event event=new Event();
            event.setDate(new Date());
            event.setEvent(String.format("The thread %s has generated an event",Thread.currentThread().getId()));
            
            // Add to the data structure
            deque.addFirst(event);
            try {
                // Sleeps during one second
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
View Code

  3 创建CleanerTask类,并继承Thread类,声明存放Event对象的队列,也实现一个带参数的构造器,来初始化这个队列,在这个构造器中用setDaemon()方法,把这个线程设为守护线程。实现run()方法,他将无线的重复运行,并在每次运行中,取当前时间,调用clean()方法。实现clean()方法,读取队列的最后一个事件对象,如果这个事件是10s钟之前创建的,将他删除并且检查下一个,如果有时间被删除,clean()将打印出删除事件的信息,

package com.packtpub.java7.concurrency.chapter1.recipe7.task;

import java.util.Date;
import java.util.Deque;

import com.packtpub.java7.concurrency.chapter1.recipe7.event.Event;

/**
 * Class that review the Event data structure and delete
 * the events older than ten seconds
 *
 */
public class CleanerTask extends Thread {

    /**
     * Data structure that stores events
     */
    private Deque<Event> deque;

    /**
     * Constructor of the class
     * @param deque data structure that stores events
     */
    public CleanerTask(Deque<Event> deque) {
        this.deque = deque;
        // Establish that this is a Daemon Thread
        setDaemon(true);
    }


    /**
     * Main method of the class
     */
    @Override
    public void run() {
        while (true) {
            Date date = new Date();
            clean(date);
        }
    }

    /**
     * Method that review the Events data structure and delete
     * the events older than ten seconds
     * @param date
     */
    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;
            }    
        } while (difference > 10000);
        if (delete){
            System.out.printf("Cleaner: Size of the queue: %d\n",deque.size());
        }
    }
}
View Code

  

  4:实现主类

  

public class Main {

    /**
     * Main method of the example. Creates three WriterTasks and a CleanerTask
     * @param args
     */
    public static void main(String[] args) {
        
        // Creates the Event data structure
        Deque<Event> deque=new ArrayDeque<Event>();
        
        // Creates the three WriterTask and starts them
        WriterTask writer=new WriterTask(deque);
        for (int i=0; i<3; i++){
            Thread thread=new Thread(writer);
            thread.start();
        }
        
        // Creates a cleaner task and starts them
        CleanerTask cleaner=new CleanerTask(deque);
        cleaner.start();

    }

}

  打印结果

Cleaner: Size of the queue: 28
Cleaner: The thread 9 has generated an event
Cleaner: Size of the queue: 28
Cleaner: The thread 11 has generated an event
Cleaner: Size of the queue: 29
Cleaner: The thread 10 has generated an event
Cleaner: Size of the queue: 28
Cleaner: The thread 9 has generated an event
Cleaner: Size of the queue: 28
Cleaner: The thread 11 has generated an event
Cleaner: Size of the queue: 29
Cleaner: The thread 10 has generated an event
Cleaner: Size of the queue: 28
Cleaner: The thread 9 has generated an event
Cleaner: Size of the queue: 28
Cleaner: The thread 11 has generated an event
Cleaner: Size of the queue: 29
Cleaner: The thread 10 has generated an event
Cleaner: Size of the queue: 29
Cleaner: The thread 9 has generated an event
Cleaner: Size of the queue: 28

我们会发现,队列中的对象会不断增长至30个,然后程序结束,队列的长度维持在27-30之间,这个程序有3个WriteTask线程,每个线程向队列写入一个事件,然后休眠1秒钟,在第一个10s中,队列中有30个事件,直到3个WriterTask都结束后,CleanTask才开始执行,但是他没有删除任何事件,因为所有的事件都小于10秒钟,在接下来运行中,CleanTask每秒钟删除3个事件,同时WriteTask会写入3个对象,所以队列一直在27-30之间。

 

  

  

  

 

posted @ 2015-07-14 13:10  有梦想的小人物  阅读(780)  评论(0编辑  收藏  举报