java多线程之守护线程Daemon()和Join()介绍

最近看了些多线程相关的同样的避免忘了:

我们先模拟一个需求,在http请求的时候我们都会发心跳包,就会一遍又一遍的去检查心跳是否存在,但是当这个请求不用的时候我们采取什么方式来把它关闭掉呢?

因为Stop的方法我们已经被java淘汰掉了.这时候我们可以拿守护线程来做着件事:

public static void main(String[] args) {

        Thread t = new Thread(() -> { //启动一个线程
            Thread innerThread = new Thread(() -> { //相当于心跳包
                try {
                    while (true) {
                        System.out.println("Do some thing for health check.");
                        Thread.sleep(1_00000); //我们假设这是在发心跳包给链接
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });

            innerThread.setDaemon(true);//守护线程是T,Daemon必须写在start前面
           innerThread.start();// 
            
            try {
                Thread.sleep(1_000);
                System.out.println("T thread finish done.");//T线程做的事情
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t.setDaemon(true);  守护线程是main
        t.start();


    }

先捋一捋上面的关系:

main--->里面有T这个线程,---->里面又包含--->InnerThread 这个线程

也就是说 --->main函数一旦停止--->T函数也停止----->T函数一旦停止---->InnerThread线程也就停止

这就叫做守护线程, 

回到上面的例子:也就是说T函数相当于一个链接,innerTheread是心跳包,当这个T链接停止的时候,Innder也就停止心跳包的发送.

Join()方法介绍 :


上面的图简单说一下需求:也就是说我们是用来采集数据的,分别用了4个线程,最后把结果都写到machines表中,但是这里面没一个线程花的时间都不一样,所以就需要Join来写:

Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程。

比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。

t.join();      //调用join方法,等待线程t执行完毕
t.join(1000);  //等待 t 线程,等待时间是1000毫秒。


模拟上面的需求:

public static void main(String[] args) throws InterruptedException {
        long startTimestamp = System.currentTimeMillis();//采集开始时间
        //模拟多个线程去访问数据库
        Thread t1 = new Thread(new CaptureRunnable("M1", 10000L));//需要花费这么多时间
        Thread t2 = new Thread(new CaptureRunnable("M2", 30000L));
        Thread t3 = new Thread(new CaptureRunnable("M3", 15000L));

        t1.start();//启动各个线程
        t2.start();
        t3.start();

        t1.join();
        t2.join();
        t3.join();

        long endTimestamp = System.currentTimeMillis();//采集结束时间
        System.out.printf("Save data begin timestamp is:%s, end timestamp is:%s\n", startTimestamp, endTimestamp);
    }

}

class CaptureRunnable implements Runnable { 

    private String machineName;//名称

    private long spendTime;//花费的时间

    public CaptureRunnable(String machineName, long spendTime) {
        this.machineName = machineName;
        this.spendTime = spendTime;
    }

    @Override
    public void run() {
        //do the really capture data.
        try {
            Thread.sleep(spendTime);//需要费时这么长时间
            System.out.printf(machineName + " completed data capture at timestamp [%s] and successfully.\n", System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public String getResult() {
        return machineName + " finish.";
    }
}

结果:

M1 completed data capture at timestamp [1521545947051] and successfully.
M3 completed data capture at timestamp [1521545952051] and successfully.
M2 completed data capture at timestamp [1521545967051] and successfully.

Save data begin timestamp is:1521545937048, end timestamp is:1521545967051

比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B。

我们看到结果:

也就是说他们在等其他线程结束

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值