线程是程序的一个执行流程,Java虚拟机允许多个线程同时并发执行。
1. 构造方法
2. 线程启动
3. 任务执行
一般由JVM来调用该方法,也可以手动调用。
a. 如果子类覆盖了run()方法,则调用子类的run()
b. 如果a不成立:
b1. 指定了target,则调用target的run()
b2. 没有指定target,该方法不做任何事并返回
所以,下面MyThread的run方法会执行:
4. 清理工作
由系统来调用该方法,在线程退出之前清理分配的资源。
5. yield方法
使当前执行线程暂停一会,让其它线程得以执行。只是临时让出时间片,不会释放拥有的锁。
6. sleep方法
使当前执行线程休眠指定的时间,不释放持有的锁。
7. join方法
等待该线程执行,直到超时或者终止。
可以作为线程通信的一种方式:A线程调用B线程的join方法(阻塞),等待B完成后再往下执行。
8. 中断
9. 守护/普通进程
JVM有很多守护进程:如垃圾回收线程等。没有前台(Non-Daemon)线程时,JVM会退出。
10. 上下文类加载器
11. 线程的优先级
a. 线程的优先级在不同的系统平台上,对应的系统优先级会不同;可能多个优先级对应同一个系统优先级。
b. 优先级高的线程并不一定会优先执行,这个由JVM来解译并向系统提供参考。
12. 线程的状态
13. 未检查异常处理器
1. 构造方法
- public Thread() {
- init(null, null, "Thread-" + nextThreadNum(), 0);
- }
- // target - 任务
- public Thread(Runnable target) {
- init(null, target, "Thread-" + nextThreadNum(), 0);
- }
- // group - 线程组,target - 任务
- public Thread(ThreadGroup group, Runnable target) {
- init(group, target, "Thread-" + nextThreadNum(), 0);
- }
- // name - 线程名称
- public Thread(String name) {
- init(null, null, name, 0);
- }
- // group - 线程组,name - 线程名称
- public Thread(ThreadGroup group, String name) {
- init(group, null, name, 0);
- }
- // target - 任务,name - 线程名称
- public Thread(Runnable target, String name) {
- init(null, target, name, 0);
- }
- // group - 线程组,target - 任务,name - 线程名称
- public Thread(ThreadGroup group, Runnable target, String name) {
- init(group, target, name, 0);
- }
- // group - 线程组,target - 任务,name - 线程名称, stackSize - 栈大小
- // 这里的stackSize只是提供一个参考值,和平台相关,JVM根据情况会做适当的调整。
- // stackSize大一些,线程就会不容易抛StackOverflowError。
- // stackSize小一些,多个线程并发执行不容易抛OutOfMemoryError。
- // 栈大小,最大递归深度和并发水平是和平台相关的。
- public Thread(ThreadGroup group, Runnable target, String name,
- long stackSize) {
- init(group, target, name, stackSize);
- }
2. 线程启动
- public synchronized void start() {
- if (threadStatus != 0 || this != me)
- throw new IllegalThreadStateException();
- group.add(this);
- start0();
- if (stopBeforeStart) {
- stop0(throwableFromStop);
- }
- }
- private native void start0();
3. 任务执行
一般由JVM来调用该方法,也可以手动调用。
a. 如果子类覆盖了run()方法,则调用子类的run()
b. 如果a不成立:
b1. 指定了target,则调用target的run()
b2. 没有指定target,该方法不做任何事并返回
- public void run() {
- if (target != null) {
- target.run();
- }
- }
所以,下面MyThread的run方法会执行:
- public class MyThread extends Thread {
- public void run() {
- System.out.println("MyThread.run()");
- }
- }
- new MyThread(new Runnable() {
- public void run() {
- System.out.println("Runnable.run()");
- }
- }).start();
4. 清理工作
由系统来调用该方法,在线程退出之前清理分配的资源。
- private void exit() {
- if (group != null) {
- group.remove(this);
- group = null;
- }
- target = null;
- threadLocals = null;
- inheritableThreadLocals = null;
- inheritedAccessControlContext = null;
- blocker = null;
- uncaughtExceptionHandler = null;
- }
5. yield方法
使当前执行线程暂停一会,让其它线程得以执行。只是临时让出时间片,不会释放拥有的锁。
- public static native void yield();
6. sleep方法
使当前执行线程休眠指定的时间,不释放持有的锁。
- public static native void sleep(long millis) throws InterruptedException;
- public static void sleep(long millis, int nanos)
- throws InterruptedException {
- if (millis < 0) {
- throw new IllegalArgumentException("timeout value is negative");
- }
- if (nanos < 0 || nanos > 999999) {
- throw new IllegalArgumentException(
- "nanosecond timeout value out of range");
- }
- if (nanos >= 500000 || (nanos != 0 && millis == 0)) { // 纳秒四舍五入,或者毫秒为0且纳秒不为0时
- millis++;
- }
- sleep(millis);
- }
7. join方法
等待该线程执行,直到超时或者终止。
可以作为线程通信的一种方式:A线程调用B线程的join方法(阻塞),等待B完成后再往下执行。
- public final synchronized void join(long millis)
- throws InterruptedException {
- long base = System.currentTimeMillis();
- long now = 0;
- if (millis < 0) {
- throw new IllegalArgumentException("timeout value is negative");
- }
- if (millis == 0) { // 0代表没有时间限制
- while (isAlive()) {
- wait(0); // 无限期的等待
- }
- } else {
- while (isAlive()) {
- long delay = millis - now;
- if (delay <= 0) {
- break;
- }
- wait(delay); // 有限期的等待
- now = System.currentTimeMillis() - base;
- }
- }
- }
- public final synchronized void join(long millis, int nanos)
- throws InterruptedException {
- if (millis < 0) {
- throw new IllegalArgumentException("timeout value is negative");
- }
- if (nanos < 0 || nanos > 999999) {
- throw new IllegalArgumentException(
- "nanosecond timeout value out of range");
- }
- if (nanos >= 500000 || (nanos != 0 && millis == 0)) { // 纳秒四舍五入,或者毫秒为0且纳秒不为0时
- millis++;
- }
- join(millis);
- }
- public final void join() throws InterruptedException {
- join(0);
- }
8. 中断
- public void interrupt() {
- if (this != Thread.currentThread())
- checkAccess();
- synchronized (blockerLock) {
- Interruptible b = blocker;
- if (b != null) {
- interrupt0(); // Just to set the interrupt flag
- b.interrupt();
- return;
- }
- }
- interrupt0();
- }
- // 静态方法:查看当前线程是否中断,并且清除中断标志。
- public static boolean interrupted() {
- return currentThread().isInterrupted(true);
- }
- // 查看该线程是否中断,但不清除中断标志。
- public boolean isInterrupted() {
- return isInterrupted(false);
- }
- private native boolean isInterrupted(boolean ClearInterrupted);
9. 守护/普通进程
JVM有很多守护进程:如垃圾回收线程等。没有前台(Non-Daemon)线程时,JVM会退出。
- public final void setDaemon(boolean on) {
- checkAccess();
- if (isAlive()) {
- throw new IllegalThreadStateException();
- }
- daemon = on;
- }
10. 上下文类加载器
- public ClassLoader getContextClassLoader() {
- if (contextClassLoader == null)
- return null;
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- ClassLoader ccl = ClassLoader.getCallerClassLoader(); // 调用者的类加载器
- if (ccl != null && ccl != contextClassLoader &&
- !contextClassLoader.isAncestor(ccl)) { // 调用者得类加载器不为空,且不和该线程的类加载器相同,也不是该类加载器的祖先时
- sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
- }
- }
- return contextClassLoader;
- }
- public void setContextClassLoader(ClassLoader cl) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new RuntimePermission("setContextClassLoader"));
- }
- contextClassLoader = cl;
- }
11. 线程的优先级
- // 最小的优先级
- public final static int MIN_PRIORITY = 1;
- // 正常的优先级
- public final static int NORM_PRIORITY = 5;
- // 最大的优先级
- public final static int MAX_PRIORITY = 10;
- public final void setPriority(int newPriority) {
- ThreadGroup g;
- checkAccess();
- if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
- throw new IllegalArgumentException();
- }
- if((g = getThreadGroup()) != null) {
- if (newPriority > g.getMaxPriority()) {
- newPriority = g.getMaxPriority();
- }
- setPriority0(priority = newPriority);
- }
- }
a. 线程的优先级在不同的系统平台上,对应的系统优先级会不同;可能多个优先级对应同一个系统优先级。
b. 优先级高的线程并不一定会优先执行,这个由JVM来解译并向系统提供参考。
12. 线程的状态
- public enum State {
- // 新建的线程,还没调用start()方法
- NEW,
- // 可以运行,需要等到其它资源(如CPU)就绪才能运行
- RUNNABLE,
- // 线程调用wait()后等待内置锁进入同步块或方法
- BLOCKED,
- // 在调用无参的wait(),Thread.join()或LockSupport.lock()方法后进入等待状态
- WAITING,
- // 调用Thread.sleep(), 有时间参数的wait(), 有时间参数的Thread.join(), LockSupport.parkNanos或LockSupport.parkUtil方法后进行有期限的等待状态
- TIMED_WAITING,
- // 执行完毕的线程状态
- TERMINATED;
- }
- public State getState() {
- // get current thread state
- return sun.misc.VM.toThreadState(threadStatus);
- }
13. 未检查异常处理器
- public interface UncaughtExceptionHandler {
- void uncaughtException(Thread t, Throwable e);
- }
- private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
- private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
- // 设置线程默认的未检查异常处理器
- public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(
- new RuntimePermission("setDefaultUncaughtExceptionHandler")
- );
- }
- defaultUncaughtExceptionHandler = eh;
- }
- public UncaughtExceptionHandler getUncaughtExceptionHandler() {
- return uncaughtExceptionHandler != null ?
- uncaughtExceptionHandler : group;
- }
- public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
- checkAccess();
- uncaughtExceptionHandler = eh;
- }
- // 只由JVM调用
- private void dispatchUncaughtException(Throwable e) {
- getUncaughtExceptionHandler().uncaughtException(this, e);
- }