守护线程:
代码:chapter4
都是放在一个ThreadGroup去管理的。
守护线程必须在start之前设置的。
public class DaemonThread {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " running");
Thread.sleep(100000);
System.out.println(Thread.currentThread().getName() + " done.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}; //new
t.setDaemon(true);
t.start();
//runnable ->running| ->dead| ->blocked
Thread.sleep(5_000); //JDK1.7
System.out.println(Thread.currentThread().getName());
}
}
为什么要设置守护线程?
创建连接线程创建之后我们用守护线程做心跳检查。创建连接线程死了则守护的心跳线程也跟着死掉了。
问题:子线程是守护线程,父亲是非守护,父亲死了,儿子就死了。
代码:
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_000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
innerThread.setDaemon(true);
innerThread.start();
try {
Thread.sleep(10000);
System.out.println("T thread finish done.");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
//t.setDaemon(true);
t.start();
System.out.println("main dead");
}
问题:子线程是非守护线程,父亲是守护线程,父亲随着main线程死,但是子线程不死,main线程死了,子线程才死。
package one.chapter4;
/***************************************
* @author:Alex Wang
* @Date:2017/2/17 QQ:532500648
* QQ交流群:286081824
***************************************/
public class DaemonThread2 {
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_000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
//innerThread.setDaemon(true);
innerThread.start();
try {
Thread.sleep(10000);
System.out.println("T thread finish done.");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t.setDaemon(true);
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("main dead");
}
}
问题:父亲线程是非守护线程,儿子是非守护线程,儿子自由。
主线程和子线程:https://blog.csdn.net/zhenwei1994/article/details/78779230
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_000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
//innerThread.setDaemon(true);
innerThread.start();
try {
Thread.sleep(10000);
System.out.println("T thread finish done.");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
//t.setDaemon(true);
t.start();
System.out.println("main dead");
}
写守护线程的时候,注意守护线程start起来之后不一定马上跑的,是runnable状态的。
------------------------------------------12------------------------------------
线程的优先级:
java8语法:http://www.ibloger.net/article/3209.html
public static void main(String[] args) {
Thread t = new Thread(() -> {
Optional.of("Hello").ifPresent(System.out::println);
try {
Thread.sleep(100_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t1");
t.start();
Optional.of(t.getName()).ifPresent(System.out::println);
Optional.of(t.getId()).ifPresent(System.out::println);
Optional.of(t.getPriority()).ifPresent(System.out::println);
}
看下这个id是怎么来的?
源码:
public long getId() {
return tid;
}
tid = nextThreadID();
private static synchronized long nextThreadID() {
return ++threadSeqNumber;
}
id就是线程的个数的值。
线程的优先级:分配时间片倾斜,不是很准,不要指望。数大优先级高。
设置优先级:https://blog.csdn.net/weixin_44071658/article/details/85008774
---------------------------13--------------------------------
join方法:
代码:chapter5
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(
() -> {
IntStream.range(1, 10).forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
}
);
t1.start();
t1.join();
IntStream.range(1, 10).forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
}
a.join()就等a执行完毕。
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(
() -> {
IntStream.range(1, 1000).forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
}
);
Thread t2 = new Thread(
() -> {
IntStream.range(1, 1000).forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
}
);
t1.start();
t2.start();
t1.join();
t2.join();
IntStream.range(1, 1000).forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
}
注意此时是join在main线程里面,Thread1和Thread2是交互执行的。
t1,t2是随机执行的。
加入等待的时长:
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(
() -> {
System.out.println("t1_start");
try {
Thread.sleep(10_100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t1_end");
}
);
Thread t2 = new Thread(
() -> {
IntStream.range(1, 1000).forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
}
);
t1.start();
// t2.start();
t1.join(10_100,10);// 毫秒+纳秒
// t2.join();
IntStream.range(1, 1000).forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));
}
必须是先start再join的。
一个问题:
启动时候是一个守护线程,比如通信什么的,主线程挂掉后就终结了。
让主线程一直等着。就是main线程等我main线程结束。
看下这个代码;
package one.chapter5;
/***************************************
* @author:Alex Wang
* @Date:2017/2/17 QQ:532500648
* QQ交流群:286081824
***************************************/
public class ThreadJoin2 {
public static void main(String[] args) {
/*Thread t1 = new Thread(() -> {
try {
System.out.println("t1 is running");
Thread.sleep(10_000);
System.out.println("t1 is done");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t1.join(100,10);
Optional.of("All of tasks finish done.").ifPresent(System.out::println);
IntStream.range(1, 1000)
.forEach(i -> System.out.println(Thread.currentThread().getName() + "->" + i));*/
//start httpServer
// JettyHttpServer.start();
// Thread.currentThread().join();
Thread main = Thread.currentThread();
Thread t1 = new Thread(() -> {
while (true) {
try {
// System.out.println("t1 is running");
// System.out.println(Thread.currentThread().isInterrupted());
if(Thread.currentThread().isInterrupted()){
System.out.println("true");
// break;
}
// Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
// break;
}
}
});
t1.start();
Thread t2 = new Thread(() -> {
try {
Thread.sleep(1000);
Thread.currentThread().interrupt();
// main.interrupt();
t1.interrupt();
// System.out.println("interrupt");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t2.start();
try {
t1.join(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end");
}
}
一个知识点:
t.join则要t.inturrept.
此时如果t线程不是sleep则不会抛出异常只会标识位显示,而且不会使join失效的。
t.join则main打断就都断了,直接end。
---
一个需求:采集服务器节点的数据。
一个很简单的数据采集系统:
public class ThreadJoin3 {
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.";
}
}
------------------------------------14---------------------------------------
没有捕获到线程中断的信号,所以还会一直运行。
如何捕获
其实是会收到信号的。
看下源码:看下仅仅是设置flag标志。
interrupt:
代码:chapter6
看下代码:
package one.chapter6.threadMy;
public class ThreadMy {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(){
public void run(){
while(true){
try{
System.out.println(123);
Thread.sleep(10_000);
}catch(InterruptedException e){
System.out.println("收到打断信号");
e.printStackTrace();
System.out.println(">>"+this.isInterrupted());
}
}
}
};
t.start();
Thread.sleep(1000);
System.out.println(t.isInterrupted());
t.interrupt();
System.out.println(t.isInterrupted());
}
}
运行结果:
代码:
执行结果:
其实还是再死循环里面的。
必须在sleep的时候才可以抛出中断异常。
注意中断了但是还是要走程序的。
只是中断了sleep或者wait。
有这几种方式:
代码,测试下wait的打断方法:
package one.chapter6.threadMy;
public class ThreadWait {
private static final Object MONITOR = new Object();
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread() {
@Override
public void run() {
while (true) {
System.out.println("888");
synchronized (MONITOR) {
try {
MONITOR.wait(10);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(isInterrupted()+"123");
}
}
}
}
};
t.start();
Thread.sleep(100);
System.out.println(t.isInterrupted());
t.interrupt();
System.out.println(t.isInterrupted());
}
}
运行结果:
虽然打断但是还是在死循环,我们可以直接stop
----------
为什么有这个方法:isInterrupted(),我们看下这个为什么没有t.,因为目前就是在线程的方法中。
我们用两种方式来定义下线程。
1.
2.我们看下源码
代码:
--------
join也是可以打断的。
代码:
Thread t = new Thread() {
@Override
public void run() {
while (true) {
}
}
};
t.start();
Thread main = Thread.currentThread();
Thread t2 = new Thread() {
@Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
main.interrupt();
System.out.println("interrupt");
}
};
t2.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
join是join到main线程,打断的应该是打断的是main线程。
sleep是t的sleep
wait是t的wait
join是join到main里面要打断main
---------------------------------15----------------------------------------