Java多线程 之 后台线程(四)

java可以设置一个线程是否是后台线程。后台线程通常作为一种服务线程而存在,并不是程序不可或缺的一部分。当所有的非后台线程退出时,整个程序也就退出了,而且会关闭进程中的所有后台线程。所以,如果在后台线程中有finally语句,则不一定会执行。看下面的例子:

package org.fan.learn.thread.deamon;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
 * Created by fan on 16-6-7.
 */
public class ADaemon implements Runnable {
    public void run() {
        System.out.println( Thread.currentThread() + "IsDaemon :" + Thread.currentThread().isDaemon() );
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println("Daemon exits");
        }
    }
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 5; i++) {
            Thread t = new Thread(new ADaemon());
            t.setDaemon(true);
            executorService.execute(t);
        }
        executorService.shutdown();
    }
}

输出如下所示:
Thread[pool-1-thread-1,5,main]IsDaemon :false
Thread[pool-1-thread-3,5,main]IsDaemon :false
Thread[pool-1-thread-2,5,main]IsDaemon :false
Thread[pool-1-thread-4,5,main]IsDaemon :false
Thread[pool-1-thread-5,5,main]IsDaemon :false
Daemon exits
Daemon exits
Daemon exits
Daemon exits
Daemon exits
上面这种写法并没有将线程置为后台线程。
当使用Thread来启动线程时可以这么写:

package org.fan.learn.thread.deamon;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
 * Created by fan on 16-6-7.
 */
public class ADaemon implements Runnable {
    public void run() {
        System.out.println( Thread.currentThread() + "IsDaemon :" + Thread.currentThread().isDaemon() );
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println("Daemon exits");
        }
    }
    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 5; i++) {
            Thread t = new Thread(new ADaemon());
            t.setDaemon(true);
            t.start();
        }
    }
}

输出如下所示:
Thread[Thread-0,5,main]IsDaemon :true
Thread[Thread-1,5,main]IsDaemon :true
Thread[Thread-2,5,main]IsDaemon :true
Thread[Thread-3,5,main]IsDaemon :true
注意,上面的有一个线程没有执行,驱动main的线程已经退出了。
使用Executor方式启动线程,需要给Executor传递ThreadFactory。

package org.fan.learn.thread.deamon;
import java.util.concurrent.ThreadFactory;
/**
 * Created by fan on 16-6-7.
 */
public class DaemonThreadFactory implements ThreadFactory {
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r);
        thread.setDaemon(true);
        return thread;
    }
}
package org.fan.learn.thread.deamon;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
 * Created by fan on 16-6-7.
 */
public class ADaemon implements Runnable {
    public void run() {
        System.out.println( Thread.currentThread() + "IsDaemon :" + Thread.currentThread().isDaemon() );
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            System.out.println("Daemon exits");
        }
    }
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool(new DaemonThreadFactory());
        for (int i = 0; i < 5; i++) {
            executorService.execute(new ADaemon());
        }
        executorService.shutdown();
    }
}

输出如下所示:
Thread[Thread-0,5,main]IsDaemon :true
Thread[Thread-1,5,main]IsDaemon :true
Thread[Thread-2,5,main]IsDaemon :true
Thread[Thread-3,5,main]IsDaemon :true
Thread[Thread-4,5,main]IsDaemon :true
至于Daemon Thread怎么正常退出,后面再续。

在《Thinking in java》第四版的21.2.8末尾有这么一句话:Executor控制的所有任务可以同时被关闭。 不懂!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值