引言
抠Thread类所有公有的方法和实现。
线程的状态:内部枚举类State
public enum State {
/**
* Thread state for a thread which has not yet started.
*/
NEW,
/**
* Thread state for a runnable thread. A thread in the runnable
* state is executing in the Java virtual machine but it may
* be waiting for other resources from the operating system
* such as processor.
*/
RUNNABLE,
/**
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}.
*/
BLOCKED,
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
*
* <p>A thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called <tt>Object.wait()</tt>
* on an object is waiting for another thread to call
* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
* that object. A thread that has called <tt>Thread.join()</tt>
* is waiting for a specified thread to terminate.
*/
WAITING,
/**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED;
}
/**
* Returns the state of this thread.
* This method is designed for use in monitoring of the system state,
* not for synchronization control.
*
* @return this thread's state.
* @since 1.5
*/
public State getState() {
// get current thread state
return sun.misc.VM.toThreadState(threadStatus);
}
需要关注一个常常被忽略的方法
public static native boolean holdsLock(Object obj);
判断当前线程是否持有锁。
状态变化的几个方法
这几个方法比较常见就不解释了~
yield()
sleep(long millis)
sleep(long millis, int nanos)
start()
join(long)
join(long, int)
join()
run()
isAlive()
这几个解释一下:
interrupt(): 线程实例请求中断
isInterrupted(): 返回线程实例是否中断
interrupted(): 当前线程(currentThread方法)是否中断
初始化
初始化主要了解两个方法:
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
public Thread(ThreadGroup group, Runnable target, String name,long stackSize) {
init(group, target, name, stackSize);
}
其余重载方法就是前三个参数的组合。
这里我们不拓展讲init方法,init方法将新线程和当前线程的绝大多数属性都设置为一致。
这里讲一下未指定线程名时会设置为"Thread-" + nextThreadNum()
,而nextThreadNum是一个同步的方法:
/* For autonumbering anonymous threads. */
private static int threadInitNumber;
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
需要注意的是,这个是只针对匿名初始化线程的!看下面的代码:
//原本的
System.out.println(new Thread().getName()); //Thread-0
System.out.println(new Thread().getName()); //Thread-1
System.out.println(new Thread().getName()); //Thread-2
//修改了中间的构造方法
System.out.println(new Thread().getName()); //Thread-0
System.out.println(new Thread("mid").getName()); //mid
System.out.println(new Thread().getName()); //Thread-1
一些其他获取属性的方法:
setPriority(int)
getPriority()
setName(String name)
getName()
getThreadGroup()
setDaemon(boolean isDaemon)
isDaemon()
getId()
getState()
Thread类中所有一些和ThreadGroup相关的方法:
activeCount() 获取当前线程组中存活的线程数量
enumerate(Thread[] tarray) 获取线程组的后辈线程数量
异常相关Debug相关
Thread中有一个和异常相关函数接口,当线程由于异常终止时不会触发JVM的异常终止,而是会调用该接口的方法。
@FunctionalInterface
public interface UncaughtExceptionHandler {
/**
* Method invoked when the given thread terminates due to the
* given uncaught exception.
* <p>Any exception thrown by this method will be ignored by the
* Java Virtual Machine.
* @param t the thread
* @param e the exception
*/
void uncaughtException(Thread t, Throwable e);
}
例如:
原本会触发JVM的异常机制:
public static void main(String[] args){
Thread thread1 = new Thread(()->{
throw new IllegalArgumentException("bug");
});
thread1.start();
}
// Exception in thread "Thread-0" java.lang.IllegalArgumentException: bug
修改后:
public static void main(String[] args){
Thread thread1 = new Thread(()->{
throw new IllegalArgumentException("bug");
});
thread1.setUncaughtExceptionHandler((Thread thread, Throwable throwable)->{
System.out.println("hhhh");
});
thread1.start();
}
//最终打印 hhhh
相应的有些方法:
setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh)
getDefaultUncaughtExceptionHandler
getUncaughtExceptionHandler
setUncaughtExceptionHandler(UncaughtExceptionHandler eh)
还有一些debug的方法也不介绍了:
getStackTrace
getAllStackTraces
checkAccess
dumpStack
上下文
setContextClassLoader(ClassLoader cl)方法和getContextClassLoader()通过下面这个例子理解~
public class SetContextLoader implements Runnable {
Thread thread;
public SetContextLoader() {
thread = new Thread(this);
thread.start();
}
public void run() {
ClassLoader classLoader = thread.getContextClassLoader();
/* Sets the context ClassLoader for this Thread. */
thread.setContextClassLoader(ClassLoader.getSystemClassLoader());
System.out.println("Class - " + classLoader.getClass());
System.out.println("Parent- " + classLoader.getParent());
}
public static void main(String args[]) {
new SetContextLoader();
}
}
输出:
Class - class sun.misc.Launcher$AppClassLoader
Parent- sun.misc.Launcher$ExtClassLoader@757aef