最近看了些多线程相关的同样的避免忘了:
我们先模拟一个需求,在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。
我们看到结果:
也就是说他们在等其他线程结束