Java 线程初始化

作者: 酱油和醋 | 来源:发表于2017-02-04 10:56 被阅读320次

    1.线程的状态

    线程1.png

    1.New新创建 2.Runnable 可运行 3.Blocked 被阻塞 4.Waiting 等待 5.Time waiting 计时等待 6. Terminated(被终止)

    2.线程的创建

    构造一个新线程,用于调用给定target的run()方法</br>

    Thread(Runnable target)
    

    启动这个线程,将引发调用run()方法</br>

    void start()
    

    调用关联Runnable的run方法</br>

    void run()
    

    不要调用Thread类或Runnable对象的run方法。直接调用run方法,只会执行同一个线程中的任务,而不会启动新的线程。应该调用Thread.start方法来创建并启动一个执行run方法的新线程.

    Thread类属性
    private volatile String name;
    private int priority;
    private Thread threadQ;
    private long eetop;
    /*Whether or not to single_step this thread*/
    private boolean single_step; 
    /*whether or not the thread is a daemon thread*/
    private boolean daemon = false;
    /*JVM state*/
    private boolean stillborn = false;
    /*what will be run*/
    private Runnable target;
    /*the group of this thread*/
    private ThreadGroup group
    /*The context ClassLoader for this thread*/
    private ClassLoader contextClassLoader;
    /*The inherited accessControlContext of this thread*/
    private AccessControlContext inheritedAccessControlContext;
    /*for autonumbering anonymous threads*/
    private static int threadInitNumber;
    private static synchronized int nextThreadNum(){return threadIdInitnumber++;}
    /* ThreadLocal values pertaining to this thread. This map is maintained
      * by the ThreadLocal class. */
      ThreadLocal.ThreadLocalMap threadLocals = null;
     /*
      * InheritableThreadLocal values pertaining to this thread. This map is
      * maintained by the InheritableThreadLocal class.
      */
      ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
     /*
      * The requested stack size for this thread, or 0 if the creator did
      * not specify a stack size. It is up to the VM to do whatever it
      * likes with this number; some VMs will ignore it.
      */
      private long stackSize;
     /*
      * JVM-private state that persists after native thread termination.
      */
      private long nativeParkEventPointer;
     /*
      * Thread ID
      */
      private long tid;
     /* For generating thread ID */
      private static long threadSeqNumber;
     /* Java thread status for tools,
      * initialized to indicate thread 'not yet started'
      */
     private volatile int threadStatus = 0;
      /**
      * The argument supplied to the current call to
      * java.util.concurrent.locks.LockSupport.park.
      * Set by (private) java.util.concurrent.locks.LockSupport.setBlocker
      * Accessed using java.util.concurrent.locks.LockSupport.getBlocker
      */
      volatile Object parkBlocker;
    
      /* The object in which this thread is blocked in an interruptible I/O
      * operation, if any. The blocker's interrupt method should be invoked
      * after setting this thread's interrupt status.
      */
      private volatile Interruptible blocker;
      /**
      * The minimum priority that a thread can have.
      */
      public final static int MIN_PRIORITY = 1;
    
      /**
      * The default priority that is assigned to a thread.
      */
      public final static int NORM_PRIORITY = 5;
    
      /**
      * The maximum priority that a thread can have.
      */
      public final static int MAX_PRIORITY = 10;
    

    其中静态成员变量 MIN_PRIORITY,NORM_PRIORITY,MAX_PRIORITY表示线程调度的优先级,默认情况下一个线程继承它的父线程的优先级。每当线程调度器有机会选择新线程时,它首先选择具有较高优先级的线程。

    线程创建的方法

    public class MyRunnable implements Runnable {
        public void run() {
            System.out.println(Thread.currentThread().getId() +  "  test runnable");
        }
    }
    public class ThreadTest {
        @Test
        public void threadRunTest(){
            System.out.println(Thread.currentThread().getId());
            MyRunnable runnable = new MyRunnable();
            runnable.run();
            for (int i = 0; i < 10; i++){
                Thread thread = new Thread(new MyRunnable());
                thread.start();
            }
    
        }
    }
    
    Thread初始化

    构造方法,调用私有init()方法</br>

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

    init()方法</br>

    private void init(ThreadGroup g, Runnable target, String name,long stackSize) {
      init(g, target, name, stackSize, null);
    }
    
     private void init(ThreadGroup g, Runnable target, String name,
      long stackSize, AccessControlContext acc) {
      if (name == null) {
      throw new NullPointerException("name cannot be null");
      }
    
      this.name = name;
    
      Thread parent = currentThread();
      SecurityManager security = System.getSecurityManager();
      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();
      }
      }
    
      /* checkAccess regardless of whether or not threadgroup is
      explicitly passed in. */
      g.checkAccess();
    
      /*
      * Do we have the required permissions?
      */
      if (security != null) {
      if (isCCLOverridden(getClass())) {
      security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
      }
      }
    
      g.addUnstarted();
    
      this.group = g;
      this.daemon = parent.isDaemon();
      this.priority = parent.getPriority();
      if (security == null || isCCLOverridden(parent.getClass()))
      this.contextClassLoader = parent.getContextClassLoader();
      else
      this.contextClassLoader = parent.contextClassLoader;
      this.inheritedAccessControlContext =
      acc != null ? acc : AccessController.getContext();
      this.target = target;
      setPriority(priority);
      if (parent.inheritableThreadLocals != null)
      this.inheritableThreadLocals =
      ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
      /* Stash the specified stack size in case the VM cares */
      this.stackSize = stackSize;
    
      /* Set thread ID */
      tid = nextThreadID();
      }
    

    init()方法参数</br>
    ThreadGroup g:ThreadGroup线程组 线程组是一个可以统一管理的线程集合。默认情况下,即没有指定线程组的话,创建的所有线程属于相同的线程组。先将secuity的线程组赋给新线程的线程组,如果还是为空,则设为父线程的线程组。

    if (security != null) {
      g = security.getThreadGroup();
    }
    if (g == null) {
      g = parent.getThreadGroup();
    } 
    this.group = g;
    

    Runnable target:Runnable对象,即装配线程要执行的run()方法,this.target = target;</br>
    String name:线程对象,默认格式Thread-“创建的线程的个数”;</br>
    nextThreadNum()方法是同步的线程安全的

    private static synchronized int nextThreadNum(){return threadIdInitnumber++;}
    

    long stackSize:线程的栈大小 根据参数传递过程可以看出默认大小为零,即使用默认的线程栈大小
    AccessControlContext acc:访问控制权限

    acc != null ? acc : AccessController.getContext();
    

    了解AccessControlContext: Java安全模式</br>
    一个新线程的初始化工作:</br>
    1.首先设置线程名称</br>
    2.将新线程的父线程设置为当前线程</br>
    3.获取系统的安全管理 SecurityManager,并获得线程组

    SecurityManager 在Java中被用来检查应用程序是否能访问一些有限的资源,例如文件、套接字(socket)等等。它可以用在那些具有高安全性要求的应用程序中。通过打开这个功能, 我们的系统资源可以只允许进行安全的操作。</br>

    4.获得的线程组权限检查</br>
    5.在线程组中增加未开始的线程数量</br>
    6.设置新线程的属性,包括线程组,从父线程继承的是否是守护线程属性,继承父线程的优先级,继承父线程的类上下文,设置新线程的访问权限,设置Runnable对象,设置inheritableThreadLocals,设置线程栈和线程Id</br>
    可以看出新线程的很多属性都是从父线程继承来的</br>

    3.守护线程

    Thread类中的daemon属性标志该线程是否是守护线程。守护线程唯一用途是为其他线程提供服务。比如说计时线程,它定时地发送计时器信号给其他线程或清空过时的高速缓存项的线程。守护线程应该永远不去访问固有资源。

    相关文章

      网友评论

        本文标题:Java 线程初始化

        本文链接:https://www.haomeiwen.com/subject/giujittx.html