并发 二 后台线程、lockInterruptibly()

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

所谓后台(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线程持有

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值