所谓后台(daemon)线程,是指程序运行的时候在后台提供一种通用服务的线程,并且这种线程并不属于程序不可或缺的部分。因此,当所有非后台线程结束时,程序也就终止了,同时会杀死进程中的所有后台线程。反过来说,只要有任何非后台线程还在运行,程序就不会终止。
class Daemon1{
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Thread threadInner = new Thread(new Runnable() {
@Override
public void run() {
while (true){
try {
TimeUnit.MILLISECONDS.sleep(400L);
System.out.println("内部线程在运行");
System.out.println("是否为后台线程:"+Thread.currentThread().isDaemon());
}catch (Exception e){
e.printStackTrace();
}
}
}
});
threadInner.start();
}
});
//一个线程(thread)为后台线程,那么此线程(thread)中创建的任何线程将被自动设置为后台线程(threadInner为后台线程)
thread.setDaemon(true);
thread.start();
try {
TimeUnit.SECONDS.sleep(2L);
}catch (Exception e){
e.printStackTrace();
}
}
}
class Daemon1{
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Thread threadInner = new Thread(new Runnable() {
@Override
public void run() {
while (true){
try {
TimeUnit.MILLISECONDS.sleep(400L);
System.out.println("内部线程在运行");
}catch (Exception e){
e.printStackTrace();
}
}
}
});
threadInner.setDaemon(true);
threadInner.start();
System.out.println("thread从run()方法返回");
}
});
thread.start();
try {
TimeUnit.MILLISECONDS.sleep(200);
}catch (Exception e){
e.printStackTrace();
}
//任务(可以理解为线程)死亡的通常方式是从run()方法返回。
// thread线程死亡/终止,thread内部创建的后台线程threadInner仍然在运行,即后台线程不会随着它的创建者死亡而死亡。
// 直到所有非后台线程死亡,后台线程才死亡。
System.out.println("thread is alive:"+thread.isAlive());
try {
TimeUnit.SECONDS.sleep(2L);
}catch (Exception e){
e.printStackTrace();
}
}
}
// lock()、lockInterruptibly()的区别
class BlockedMutex {
public static final Lock lock = new ReentrantLock();
public BlockedMutex() {
//创建对象的时候就获取锁,并且不释放锁。
lock.lock();
}
public void f() {
try {
//由于main线程一直持有锁lock,不释放,本线程一直处于锁互斥阻塞状态。
//普通lock同步代码,因调用wait(),join(),sleep()而导致处于阻塞状态,此时可以响应中断。
// 本线程一直处于获取锁的状态,即因拿不到锁而阻塞,此时不会响应中断
//lock.lock();
// 使用lockInterruptibly(),当线程处于获取锁的状态时也可以响应中断。
lock.lockInterruptibly();
System.out.println("本线程永远得不到锁,此代码无法执行");
} catch (Exception e) {
System.out.println("线程响应中断,抛出异常,释放锁");
}
}
}
class Blocked2 implements Runnable {
BlockedMutex blocked = new BlockedMutex();
public void run() {
System.out.println("BlockedMutex.f()开始执行");
blocked.f();
System.out.println("退出run,线程死亡");
}
}
class Interrupting2 {
public static void main(String[] args) throws Exception {
Thread t = new Thread(new Blocked2());
t.start();
TimeUnit.SECONDS.sleep(1);
System.out.println("线程t,发出中断,线程是否响应?");
t.interrupt();
}
}
通过debug可以看出lock被main线程持有

本文探讨了Java中后台线程的概念及行为特征,并通过示例代码展示了如何创建后台线程及其运行特性。此外,还对比了lock()与lockInterruptibly()两种不同锁获取方式的特点。

1328

被折叠的 条评论
为什么被折叠?



