【并发编程】Thread 类的详细介绍
Map<Thread, StackTraceElement[]> allStackTraces = Thread.getAllStackTraces();
//获取类加载器
ClassLoader contextClassLoader = thread.getContextClassLoader();
//获取当前线程名字
String threadName = thread.getName();
System.out.println("current thread name["+threadName+"]");
//获取当前线程 ID
long threadId = thread.getId();
System.out.println("current thread id["+threadId+"]");
//获取当前线程的优先级,一共有 1~10 总共 10 个优先级,这个优先级并不是在
//所有平台都生效的
int priority = thread.getPriority();
System.out.println("current thread priority["+priority+"]");
StackTraceElement[] stackTrace = thread.getStackTrace();
System.out.println("-------------stackTrace info--------------");
for (int i = 0; i < stackTrace.length; i++) {
StackTraceElement element = stackTrace[i];
System.out.println("className:["+element.getClassName()+"]");
System.out.println("fileName:["+element.getFileName()+"]");
System.out.println("line nunber:["+element.getLineNumber()+"]");
System.out.println("method name:["+element.getMethodName()+"]");
System.out.println("is native method:["+element.isNativeMethod()+"]");
System.out.println("------------------------------------------");
}
Thread.State state = thread.getState();
System.out.println("thread state:["+state+"]");
ThreadGroup threadGroup = thread.getThreadGroup();
String threadGroupName = threadGroup.getName();
System.out.println("thread group name:["+threadGroupName+"]");
//线程睡眠,调用 sleep 方法会使得线程进入 timed_waiting 状态,如果线程已经
//获得了锁资源,调用 sleep 方法是不会释放这个锁的
Thread.sleep(2000,500);
Thread.sleep(1000);
TimeUnit.SECONDS.sleep(2);
Thread thread1 = new Thread(new Runnable() {
@SneakyThrows
@Override
public void run() {
TimeUnit.SECONDS.sleep(100);
}
});
thread1.start();
thread1.join(50);
}
}
守护线程
守护线程可以理解为服务线程,他们的作用就是服务于其他用户线程。当系统中不存在其他用户线程时,这些守护线程也会自动消亡。比如 JVM 的垃圾清理线程就是守护线程。我们可以使用如下方法查看和设置线程是否是守护线程。
thread.isDaemon();
thread.setDaemon(true);
join 方法
调用线程的 join 方法会使得调用线程进入 waiting 状态,直到被调用的线程执行结束,调用线程才会重新获得执行的机会。
public class MyThread {
public static void main(String[] args) throws Exception {
Thread thread1 = new Thread(new Runnable() {
@SneakyThrows
@Override
public void run() {
TimeUnit.SECONDS.sleep(100);
}
});
thread1.start();
thread1.join();
System.out.println("main thread end...");
}
}
上面的代码中,main 线程调用了 thread1 的 join 方法,main 线程会被挂起进入 waiting 状态,直到 thread1 执行完毕之后,main 线程才有机会重新获得执行机会。
join 方法还有一个重载方法,这个方法可以指定超时时间。
thread1.join(50);
如果 thread1 线程在 50ms 内还没执行完,main 线程就可以重新获得执行机会。
yeild 方法
调用线程的 yield 方法不是一定会成功。
退让成功时,退让线程会由 Running(运行)转为 Runnable(就绪)状态。
退让了的线程,与其他同优先级级别的线程一样,同样有再次获取 CPU 使用权的机会。
中断
--
先贴上一段网友对线程中断的总结。
除非是线程自己 interrupt()自己,否则 checkAccess()方法都会被调用,并可能抛出一个 SecurityException 异常。
如果当前线程处于 blocked 阻塞(因为调用 wait、sleep 和 join 造成的)状态时被 interrupt 了,那么[中断标志位]将被清除,并且收到一个 InterruptedException 异常。
如果当前线程处于 blocked 阻塞(因为 NIO 的 In
terruptibleChannel 进行的 I/O 操作造成的)状态时被 interrupt 了,则会关闭 channel,[中断标志位]将会被置为 true,并且当前线程会收到一个 ClosedByInterruptException 异常。
如果当前线程处于 blocked 阻塞(因为 NIO 的 Selector 造成的)状态时被 interrupt 了,那么[中断标志位]将被置为 true,然后当前线程会立即从选择器区域返回并返回值(可能为非零的值)。
如果前面的情况都没有发生,则线程会将[中断标志位]将被置为 true。
评论