java Thread源码分析

一、使用 java 多线程

java多线程其中两种使用方式:

1、继承 Thread 类

2、实现 Runnable 接口

 1 public class ThreadTest {
 2     public static void main(String[] args) {
 3         Thread t1 = new MyThread("thread-0001");
 4         t1.start();
 5         MyRunnable mr = new MyRunnable();
 6         Thread t2 = new Thread(mr, "thread-0002");
 7         t2.start();
 8     }
 9     private static class MyThread extends Thread{
10         public MyThread(String name) {
11             this.setName(name);
12         }
13         @Override
14         public void run() {
15             System.out.println(this.getName()+" thread run....");
16         }
17     }
18     private static class MyRunnable implements Runnable{
19         @Override
20         public void run() {
21             System.out.println(Thread.currentThread().getName()+" runable run....");    
22         }
23     }
24 }

 

二、线程初始化

  继承 Thread 和 实现 Runnable 的方式都要经过初始化Thread构造函数的方式设置相关参数的过程。

  构造函数如下:

public Thread() {
    init(null, null, "Thread-" + nextThreadNum(), 0);
}

public Thread(Runnable target) {
    init(null, target, "Thread-" + nextThreadNum(), 0);
}

public Thread(ThreadGroup group, Runnable target) {
    init(group, target, "Thread-" + nextThreadNum(), 0);
}

public Thread(String name) {
    init(null, null, name, 0);
}

public Thread(ThreadGroup group, String name) {
    init(group, null, name, 0);
}

public Thread(Runnable target, String name) {
    init(null, target, name, 0);
}

public Thread(ThreadGroup group, Runnable target, String name) {
    init(group, target, name, 0);
}

public Thread(ThreadGroup group, Runnable target, String name, long stackSize) {
    init(group, target, name, stackSize);
}
View Code
  上述构造函数涉及的参数:
  ThreadGroup group(该线程所属线程组)、Runnable targer、String name(线程名)、long stackSize(线程堆栈大小,不知道有什么作用,日后再填坑)。
  最终会执行 init 函数:
 1 private void init(ThreadGroup g, Runnable target, String name,
 2                       long stackSize, AccessControlContext acc,
 3                       boolean inheritThreadLocals) {
 4         if (name == null) {
 5             throw new NullPointerException("name cannot be null");
 6         }
 7         
 8         // 线程名
 9         this.name = name;
10 
11         // 创建该线程时的线程(即父线程)
12         Thread parent = currentThread();
13         SecurityManager security = System.getSecurityManager();
14         // 线程组
15         if (g == null) {
16             /* Determine if it's an applet or not */
17 
18             /* If there is a security manager, ask the security manager
19                what to do. */
20             if (security != null) {
21                 g = security.getThreadGroup();
22             }
23 
24             /* If the security doesn't have a strong opinion of the matter
25                use the parent thread group. */
26             // 没有设置线程组时,默认线程组为父线程的线程组
27             if (g == null) {
28                 g = parent.getThreadGroup();
29             }
30         }
31 
32         /* checkAccess regardless of whether or not threadgroup is
33            explicitly passed in. */
34         g.checkAccess();
35 
36         /*
37          * Do we have the required permissions?
38          */
39         if (security != null) {
40             if (isCCLOverridden(getClass())) {
41                 security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
42             }
43         }
44 
45         g.addUnstarted();
46 
47         // 设置线程组
48         this.group = g;
49         // 设置
50         this.daemon = parent.isDaemon();
51         // 设置优先级和父线程的优先级相同
52         this.priority = parent.getPriority();
53         if (security == null || isCCLOverridden(parent.getClass()))
54             this.contextClassLoader = parent.getContextClassLoader();
55         else
56             this.contextClassLoader = parent.contextClassLoader;
57         this.inheritedAccessControlContext =
58                 acc != null ? acc : AccessController.getContext();
59         // Runnable target
60         this.target = target;
61         setPriority(priority);
62         if (inheritThreadLocals && parent.inheritableThreadLocals != null)
63             this.inheritableThreadLocals =
64                 ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
65         /* Stash the specified stack size in case the VM cares */
66         this.stackSize = stackSize;
67 
68         /* Set thread ID */
69         // 设置线程的ID(threadSeqNumber),同步递增,每个线程都会生成一个thread ID
70         // 另外一个同步递增的ID (threadInitNumber),这个在没有显式指定线程名的时候,默认生成线程名(Thread-N)。
71         // 所以,threadSeqNumber >= threadInitNumber
72         tid = nextThreadID();
73     }
View Code
  t1.start()会调用本地方法start0()启动线程:
 1 public synchronized void start() {
 2         /**
 3          * This method is not invoked for the main method thread or "system"
 4          * group threads created/set up by the VM. Any new functionality added
 5          * to this method in the future may have to also be added to the VM.
 6          *
 7          * A zero status value corresponds to state "NEW".
 8          */
 9         if (threadStatus != 0)
10             throw new IllegalThreadStateException();
11 
12         /* Notify the group that this thread is about to be started
13          * so that it can be added to the group's list of threads
14          * and the group's unstarted count can be decremented. */
15         // 将线程添加到线程组中
16          group.add(this);
17 
18         boolean started = false;
19         try {
20             // navite修饰的方法
21             start0();
22             started = true;
23         } finally {
24             try {
25                 if (!started) {
26                     // 线程启动失败,从线程组中移除线程
27                     group.threadStartFailed(this);
28                 }
29             } catch (Throwable ignore) {
30                 /* do nothing. If start0 threw a Throwable then
31                   it will be passed up the call stack */
32             }
33         }
34     }
View Code
 
posted @ 2018-12-30 23:09  S3c0ldW4ng  阅读(274)  评论(0编辑  收藏  举报