package com.iteye.yuanyuan7891.thread.DaemonTest;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.LockInfo;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MonitorInfo;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.List;
/**
* @author sky
* 在Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程)<br>
* Daemon的作用是为用户线程的运行提供服务,比如说GC线程。<br>
* 当虚拟机中没有用户线程时虚拟机会退出.<br>
* 正在运行的常规线程不能设置为守护线程。<br>
* thread.setDaemon(true)必须在thread.start()之前设置,否则会跑出一个IllegalThreadStateException异常。<br>
* 在Daemon线程中产生的新线程也是Daemon的(这里要和linux的区分,linux中守护进程fork()出来的子进程不再是守护进程)<br>
*/
public class DaemonTest {
public static void main(String[] args) {
Thread daemonThread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("daemonThread 线程结束....");
}
});
daemonThread.setName("我是守护进程哦");
//设置为守护线程,试试注释下面的语句
daemonThread.setDaemon(true);
daemonThread.start();
Thread userThread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread 线程结束,如果没有其他用户进程,虚拟机会退出,守护进程会被结束,你将看不到守护进程的打印.");
}
});
userThread.start();
System.out.println("main线程 结束....");
}
static {
/**
* 打印JVM退出堆栈信息
*/
jvmExitHook();
}
public static void jvmExitHook() {
System.out.println("注册JVM Shutdown钩子方法---------");
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.out.println("JVM将要退出 退出信息打印:");
MemoryMXBean memorymbean = ManagementFactory.getMemoryMXBean();
System.out.println("####################内存信息####################");
System.out.println("Heap Memory: " + memorymbean.getHeapMemoryUsage());
System.out.println("Non Heap Memory: " + memorymbean.getNonHeapMemoryUsage());
List<GarbageCollectorMXBean> list = ManagementFactory.getGarbageCollectorMXBeans();
if (list != null && list.size() > 0) {
System.out.println("####################Gc信息####################");
for (GarbageCollectorMXBean gcBean : list) {
String s = "gc name=" + gcBean.getName() + ",gc count=" + gcBean.getCollectionCount()
+ ",gc time=" + gcBean.getCollectionTime();
System.out.println(s);
}
}
ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
long[] ids = threadBean.getAllThreadIds();
System.out.println("####################线程信息####################");
for (long id : ids) {
ThreadInfo threadInfo = threadBean.getThreadInfo(id, Integer.MAX_VALUE);
if (threadInfo != null) {
String s = "blockcount=" + threadInfo.getBlockedCount() + ",blocktime="
+ threadInfo.getBlockedTime();
s = s + ",waitedcount=" + threadInfo.getWaitedCount() + ",waitedtime="
+ threadInfo.getWaitedTime();
System.out.println(s);
System.out.println(getThreadInfo(threadInfo));
}
}
long[] deadlock_ids = threadBean.findDeadlockedThreads();
if (deadlock_ids != null) {
System.out.println("####################死锁信息####################");
for (long id : deadlock_ids) {
System.out.println("死锁的线程号:" + id);
}
}
}
});
}
public static String getThreadInfo(ThreadInfo t) {
try {
StringBuilder sb = new StringBuilder(
"\"" + t.getThreadName() + "\"" + " Id=" + t.getThreadId() + " " + t.getThreadState());
if (t.getLockName() != null) {
sb.append(" on " + t.getLockName());
}
if (t.getLockOwnerName() != null) {
sb.append(" owned by \"" + t.getLockOwnerName() + "\" Id=" + t.getLockOwnerId());
}
if (t.isSuspended()) {
sb.append(" (suspended)");
}
if (t.isInNative()) {
sb.append(" (in native)");
}
sb.append('\n');
int i = 0;
for (StackTraceElement ste : t.getStackTrace()) {
sb.append("\tat " + ste.toString());
sb.append('\n');
if (i == 0 && t.getLockInfo() != null) {
Thread.State ts = t.getThreadState();
switch (ts) {
case BLOCKED:
sb.append("\t- blocked on " + t.getLockInfo());
sb.append('\n');
break;
case WAITING:
sb.append("\t- waiting on " + t.getLockInfo());
sb.append('\n');
break;
case TIMED_WAITING:
sb.append("\t- waiting on " + t.getLockInfo());
sb.append('\n');
break;
default:
}
}
for (MonitorInfo mi : t.getLockedMonitors()) {
if (mi.getLockedStackDepth() == i) {
sb.append("\t- locked " + mi);
sb.append('\n');
}
}
}
if (i < t.getStackTrace().length) {
sb.append("\t...");
sb.append('\n');
}
LockInfo[] locks = t.getLockedSynchronizers();
if (locks.length > 0) {
sb.append("\n\tNumber of locked synchronizers = " + locks.length);
sb.append('\n');
for (LockInfo li : locks) {
sb.append("\t- " + li);
sb.append('\n');
}
}
sb.append('\n');
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}