java创建一个守护线程_JAVA 并发编程之守护线程的创建与运行

java里有一种特殊的线程叫做守护线程(Daemon)线程。这种线程的优先级很低,通常来说,当同一个应用程序里没有其他的线程运行的时候,守护线程才运行。当程序中唯一运行的的线程是守护线程时,并且守护线程执行结束后 ,JVM也就结束了这个程序。

因为这种特性,守护线程通常被用来作为同一程序中普通线程(用户线程)的服务提供者。它们通常是无线循环的,以等待服务请求或者执行线程的任务。它们不能做重要工作,因为我们不可能知道守护线程什么时候获取CPU时钟,并且,在没有其他线程运行时,守护线程随时可以结束。典型应用就是JAVA GC。

如何创建守护线程,写一个简单的DEMO。场景如下:有两线程,一种是用户线程,它将事件写到一个队列中。另一个是守护线程。他将管理这个队列。如果生成的事件超过10秒钟,就会被移除。

1.创建一个Event类。在类中声明两个私有属性,一个日期类型属性date;另一个字符串类型的属性event.并生成这两个属性的读写方法。

public class Event {

private Date date;

private String event;

public Date getDate() {

return date;

}

public void setDate(Date date) {

this.date = date;

}

public String getEvent() {

return event;

}

public void setEvent(String event) {

this.event = event;

}

2.创建WriterTask类,用以实现Runnable接口。

public class WriterTask implements Runnable{}

3.声明一个存放Event对象的队列,并实现带参数的构造器,来初始化这个队列对象。

Deque deque;

public WriterTask(Deque deque) {

this.deque = deque;

}

4.实现线程的run()方法。它将执行100次循环。在每次循环中,都会创建一个新的Event对象,并放入队列中。然后休眠一秒钟。

public void run(){

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

Event event=new Event();

event.setDate(new Date());

event.setEvent(String.format("The thread %s has generated an event", Thread.currentThread().getId()));

deque.addFirst(event);

try{

TimeUnit.SECONDS.sleep(1);

}catch(InterruptedException e){

e.printStackTrace();

}

}

}

5.创建CleanerTask类并继承Thrad类。

public class CleanerTask extends Thread{}

6.声明存放Event对象的队列,并实现构造器,来初始化这个队列对象。同时,在这个构造器中,通过setDaemon()方法把这个线程设置为守护线程。

Deque deque;

public CleanerTask(Deque deque) {

this.deque = deque;

setDaemon(true);

}

7.实现run()方法,它会无限制的重复运行,在每次运行中,将获取当前的时间,并调用clean()方法。

public void run(){

while(true){

Date date=new Date();

clean(date);

}

}

8.实现clean()方法。clean()方法将读取队列的最后一个事件对象,如果这个事件是10秒种前创建的,就将它删除并且检查下一个。如果有事件被删除,clean()讲打印被删除事件信息,讲打印队列长度。

public void clean(Date date){

long diffrence;

boolean delete;

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

return;

}

delete=false;

do{

Event e=deque.getLast();

diffrence=date.getTime()-e.getDate().getTime();

if(diffrence>10000){

System.out.printf("Cleaner:%s\n",e.getEvent());

deque.removeLast();

delete=true;

}

}while(diffrence>10000);

if(delete){

System.out.printf("Cleaner: Size of the queue: %d\n",deque.size());

}

}public void clean(Date date){

long diffrence;

boolean delete;

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

return;

}

delete=false;

do{

Event e=deque.getLast();

diffrence=date.getTime()-e.getDate().getTime();

if(diffrence>10000){

System.out.printf("Cleaner:%s\n",e.getEvent());

deque.removeLast();

delete=true;

}

}while(diffrence>10000);

if(delete){

System.out.printf("Cleaner: Size of the queue: %d\n",deque.size());

}

9.创建一个包含main()方法的Main主类。

public class Main {

public static void main(String[] args) {}}

10.创建一个队列对象Deque,用来存放事件。

Deque deque=new ArrayDeque();

11.创建三个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.运行,查看结果。发现,队列对象会不断增长到30个,然后到程序结束,队列长度维持在27-30之间,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值