首页 > 编程语言 > 详细

线程的继承以及线程组的划分

时间:2019-02-23 18:09:22      阅读:143      评论:0      收藏:0      [点我收藏+]

java的三大特性之一,继承;那线程之间是否有继承关系?看一下thread的源码。

 1 /**
 2      * Initializes a Thread.
 3      *
 4      * @param g the Thread group
 5      * @param target the object whose run() method gets called
 6      * @param name the name of the new Thread
 7      * @param stackSize the desired stack size for the new thread, or
 8      *        zero to indicate that this parameter is to be ignored.
 9      * @param acc the AccessControlContext to inherit, or
10      *            AccessController.getContext() if null
11      * @param inheritThreadLocals if {@code true}, inherit initial values for
12      *            inheritable thread-locals from the constructing thread
13      */
14     private void init(ThreadGroup g, Runnable target, String name,
15                       long stackSize, AccessControlContext acc,
16                       boolean inheritThreadLocals) {
17         if (name == null) {
18             throw new NullPointerException("name cannot be null");
19         }
20 
21         this.name = name;
22 
23         Thread parent = currentThread();
24         SecurityManager security = System.getSecurityManager();
25         if (g == null) {
26             /* Determine if it‘s an applet or not */
27 
28             /* If there is a security manager, ask the security manager
29                what to do. */
30             if (security != null) {
31                 g = security.getThreadGroup();
32             }
33 
34             /* If the security doesn‘t have a strong opinion of the matter
35                use the parent thread group. */
36             if (g == null) {
37                 g = parent.getThreadGroup();
38             }
39         }
40 
41         /* checkAccess regardless of whether or not threadgroup is
42            explicitly passed in. */
43         g.checkAccess();
44 
45         /*
46          * Do we have the required permissions?
47          */
48         if (security != null) {
49             if (isCCLOverridden(getClass())) {
50                 security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
51             }
52         }
53 
54         g.addUnstarted();
55 
56         this.group = g;
57         this.daemon = parent.isDaemon();
58         this.priority = parent.getPriority();
59         if (security == null || isCCLOverridden(parent.getClass()))
60             this.contextClassLoader = parent.getContextClassLoader();
61         else
62             this.contextClassLoader = parent.contextClassLoader;
63         this.inheritedAccessControlContext =
64                 acc != null ? acc : AccessController.getContext();
65         this.target = target;
66         setPriority(priority);
67         if (inheritThreadLocals && parent.inheritableThreadLocals != null)
68             this.inheritableThreadLocals =
69                 ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
70         /* Stash the specified stack size in case the VM cares */
71         this.stackSize = stackSize;
72 
73         /* Set thread ID */
74         tid = nextThreadID();
75     }

纵观thread的所有构造函数中,都调用了init方法,不难从中发现线程之间的父子关系。

if (name == null) {
            throw new NullPointerException("name cannot be null");
        }

name:即线程的名称,可以自定义,默认采用Thread-+数字给线程命名。

 Thread parent = currentThread();
 SecurityManager security = System.getSecurityManager();

在线程的生命周期中,如果一个线程new出来之后,在start之前,只是一个thread实例,并没有创建一个新的线程,所以这里的 Thread parent = currentThread(); 代表的是创建它的那个线程。

因此可以得出结论:

  1.一个线程一定是由另一个线程创建的。

  2.被创建的线程的父线程 是创建它的线程。

  3.main函数所在的线程是由jvm创建的,因此推断出所有的线程的父线程是main线程。

    if (g == null) {
            /* Determine if it‘s an applet or not */

            /* If there is a security manager, ask the security manager
               what to do. */
            if (security != null) {
                g = security.getThreadGroup();
            }

            /* If the security doesn‘t have a strong opinion of the matter
               use the parent thread group. */
            if (g == null) {
                g = parent.getThreadGroup();
            }
        }

init方法中,第一个参数为 ThreadGroup,从上面的代码块看出,如果没有传入线程组,则默认加入父线程所在的线程组。下面代码测试一下:

public static void main(String[] args) {
        Thread t1 = new Thread("t1");

        ThreadGroup group = new ThreadGroup("group1");

        Thread t2 = new Thread(group, "t2");

        ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();

        System.out.println("父线程组 name:"+threadGroup.getName());
        System.out.println("t1所在线程组 name:"+t1.getThreadGroup().getName());
        System.out.println("t2所在线程组 name:"+t2.getThreadGroup().getName());
    }

结果:

  父线程组 name:main
  t1所在线程组 name:main
  t2所在线程组 name:group1

这里我们先创建线程t1,线程组group1,线程t2,在创建t2的时候,将group1做为参数传递到线程t2的创建中,而t1并没有指定线程组。

分别获取当前线程的线程组name,t1的线程组name,t2的线程组name,可见t1因为没有指定线程组,被加到了当前线程的线程组中。

线程的继承以及线程组的划分

原文:https://www.cnblogs.com/fengyue0520/p/10423516.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!