代码:
线程的阻塞是不能打断的就是被synchronized阻塞的线程。
线程的run方法是不能抛出异常的:https://www.cnblogs.com/wxqsly/p/4275067.html
钩子函数:https://my.oschina.net/u/3768341/blog/1842994
线程死掉外面是不知道发生了什么的。
如何处理?
kill -9停掉的化网络资源不会立即释放,操作系统会释放。
jvm两种模式。server模式会进行即使编译,多线程会有happend-before问题。
写一个简单的钩子函数程序,部署在虚拟机里面,直接在虚拟机里面写:
package chapter11;
public class Exit {
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.println("The application will be exit.");
notifyAndRelease();
}));
int i = 0;
while (true) {
try {
Thread.sleep(1_000L);
System.out.println("I am working");
} catch (Throwable e) {
}
i++;
if (i > 20) {
throw new RuntimeException("Erroe");
}
}
}
public static void notifyAndRelease() {//抛出异常之后做的事
System.out.println("notify to the admin.");//通知主机
try {
Thread.sleep(1_000);
} catch (Exception e) {
}
System.out.println("will release reource(socket file connection)");//释放资源
try {
Thread.sleep(1_000);
} catch (Exception e) {
}
System.out.println("done");//完成
}
}
输出为:
javac Exit.java
nohup java Exit &
tail -f nohup.out
------------
在kill 的时候我们要获得一个通知。
kill用钩子也是可以的。
kill -9不可以的就真的杀掉了,钩子也没用了。
--------------------------------------------------31----------------------------------------------------
代码:
------
线程里面是抛异常不可以的,只能够捕获的。
1.
public class ThreadException {
private final static int A = 10;
private final static int B = 0;
public static void main(String[] args) {
//new Test1().test();
Thread t = new Thread(() -> {
try {
Thread.sleep(5_000L);
int result = A / B;
System.out.println(result);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
// t.start();
t.setUncaughtExceptionHandler((thread, e) -> {
System.out.println(e);
System.out.println(thread);
});
t.start();
}
}
这个是一个内部类。
--------
2.一个有趣的实验工作不常用的:
public class Test1
{
private Test2 test2 = new Test2();
public void test(){
test2.test();
}
}
public class Test2 {
public void test() {
Arrays.asList(Thread.currentThread().getStackTrace()).stream()
.filter(e -> !e.isNativeMethod())
.forEach(e -> Optional.of(e.getClassName() + ":" + e.getMethodName() + ":" + e.getLineNumber())
.ifPresent(System.out::println)
);
}
}
打印:
14 14 5等是行数。
----------------------------------------------------------32------------------------------------------------------
run方法是不能抛出异常的,这个是由方法签名决定的。
ThreadGroup:ThreadGroup----->Thread
在jvm启动的时候有一个根的ThreadGroup,其包含ThreadGroup和Thread。
代码:
打印:
public class ThreadMainGroup {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
System.out.println(Thread.currentThread().getThreadGroup().getName());
}
}
都是main。main也是一个线程。
public class ThreadGroupGet {
public static void main(String[] args) {
ThreadGroup tg1 = new ThreadGroup("TG1");
Thread t1 = new Thread(tg1, "t1") {
@Override
public void run() {
while (true) {
try {
System.out.println(getThreadGroup().getName());
System.out.println(getThreadGroup().getParent());
System.out.println(getThreadGroup().getParent().activeCount());
Thread.sleep(10_0000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
t1.start();
//同一个父亲的
ThreadGroup tg2 = new ThreadGroup("TG2");
Thread t2 = new Thread(tg2, "T2") {
@Override
public void run() {
System.out.println(">>>"+tg1.getName());
Thread[] threads = new Thread[tg1.activeCount()];
tg1.enumerate(threads);
Arrays.asList(threads).forEach(System.out::println);
}
};
t2.start();
}
}
-----------------------------------------------------------33-------------不看了用的比较少-----------------------------------------
ThreadGroup的API:
package chapter12;
import java.util.Arrays;
public class ThreadGroupFatherAndSon {
public static void main(String[] args) throws InterruptedException {
ThreadGroup tg1 = new ThreadGroup("TG1");
Thread t1 = new Thread(tg1, "t1") {
@Override
public void run() {
try {
Thread.sleep(1_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t1.start();
ThreadGroup tg2 = new ThreadGroup(tg1, "TG2");
Thread t2 = new Thread(tg2, "T2") {
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
};
t2.start();
System.out.println(tg1.activeCount());//输出为2
System.out.println(tg1.activeGroupCount());//输出为1
tg2.checkAccess();//是否可以更改 就是当前的线程是不是能改tg2
tg1.destroy();//必须是不在运行的线程在group里面
Thread[] ts1 = new Thread[tg1.activeCount()];
tg1.enumerate(ts1);//true就是那所有的 false就是自己的 不是递归
Arrays.asList(ts1).forEach(System.out::println);
tg1.interrupt();//它中断了儿子什么的都中断了
}
}
----
ThreadGroup要是你不显示的destory,其生命周期是比较长的。
-----
例子:destory,线程执行结束就destory线程组。
public class Destory {
public static void main(String[] args) throws InterruptedException {
ThreadGroup tg1 = new ThreadGroup("TG1");
Thread t1 = new Thread(tg1, "t1") {
@Override
public void run() {
//while (true) {
try {
Thread.sleep(1_000);
} catch (InterruptedException e) {
e.printStackTrace();
// break;
}
//}
}
};
tg1.setDaemon(false);
t1.start();
Thread.sleep(2_000);
System.out.println(tg1.isDestroyed());//输出为true tg1.setDaemon(true);
tg1.destroy();
System.out.println(tg1.isDestroyed());//输出为true
}
}
-----------------------------------------------------------------34------不看了用的比较少------------------------------------------------