- A+
所属分类:首页
本博客系列是进修并发编程过程当中的纪录总结。由于文章比较多,写的时刻也比较散,所以我整理了个目次贴(传送门),轻易查阅。
Thread
类是Java中完成多线程编程的基本类。本篇博客就来引见下Thread
类的经常运用API和罕见用法。
Thread
类经常运用的要领以下:
- Thread.activeCount():这个要领用于返回当前线程的线程组中运动线程的数目,返回的值只是一个估计值,由于当此要领遍历内部数据结构时,线程数大概会动态变动。)。
- Thread.checkAccess(): 磨练当前正在实行的线程是不是有权限修正thread的属性,这个要领我们平常不自身举行挪用,Thread类的set要领在举行属性修正时都邑先挪用这个要领。
- Thread.currentThread():猎取当前正在运转的线程。
- Thread.dumpStack():输出线程栈,平常在debug的时刻挪用。
- Thread.enumerate(Thread tarray[]):??运用场景。
- Thread.getAllStackTraces():猎取体系中一切线程的线程栈信息。
- thread.getName():猎取线程的名字。
- thread.getPriority():猎取线程的优先级。
- thread.getStackTrace():猎取客栈信息。
- thread.getState():猎取线程状况。
- thread.getThreadGroup():猎取线程地点线程组。
- thread.interrupt():使得指定线程中断壅塞状况,并将壅塞标志位置为true。
- thread.interrupted():测试当前线程是不是被中断。
- thread.isAlive():推断线程是不是还存在世。
- thread.isDaemon():推断线程是不是是保卫线程。
- thread.join():在当前线程中到场指定线程,使得当前线程必需守候指定线程运转终了以后,才终了。能够明白成线程插队、守候该线程停止。
- Thread.sleep(long):强迫线程就寝一段时刻。
- thread.start():启动一个线程。
- thread.setName(name):设置线程的名字。
- thread.setPriority(priority):设置线程的优先级。
- thread.setDaemon(true):将指定线程设置为保卫线程。
- thread.yield():使得当前线程让步出CPU资本,把CPU调理时机分配给一样线程优先级的线程。
- object.wait()、object.notify()、object.notifyAll():Object类供应的线程守候和线程叫醒要领。
示例代码
public class MyThread {
public static void main(String[] args) {
Thread thread = Thread.currentThread();
//这个要领返回的是当前线程地点线程组以及这个线程组的子线程组内运动的线程数
//这个值是一个估计值,所以这个要领的运用场景不大
int activeCount = Thread.activeCount();
System.out.println("当前体系中运动线程数["+activeCount+"]");
//向规范毛病输出流输出当前的线程栈,不会阻断顺序的继承实行
Thread.dumpStack();
//猎取一切线程栈信息
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的InterruptibleChannel举行的I/O操纵形成的)状况时被interrupt了,则会封闭channel,[中断标志位]将会被置为true,而且当前线程会收到一个ClosedByInterruptException非常。
- 假如当前线程处于blocked壅塞(由于NIO的Selector形成的)状况时被interrupt了,那末[中断标志位]将被置为true,然后当前线程会立即从选择器地区返回并返回值(大概为非零的值)。
- 假如前面的状况都没有发作,则线程会将[中断标志位]将被置为true。
越发易懂的说法(不包括NIO部份):
- interrupt()要领并非中断线程,而是中断壅塞状况,或许将线程的[中断标志位]置为true。
- 关于未壅塞的线程,interrupt()只是形成[中断标志位]=rue,线程自身运转状况不受影响。
- 关于壅塞的线程,interrupt()会中断壅塞状况,使其转换成非壅塞状况,并消灭[中断标志位]。
- 形成壅塞状况的状况有:sleep()、wait()和join()。
- 壅塞状况的线程被中断时,只是中断了壅塞状况,即sleep()、wait()和join(),线程自身还在继承运转。