zoukankan      html  css  js  c++  java
  • 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
     
  • 相关阅读:
    Apache CXF实战之四 构建RESTful Web Service
    使用CXF开发RESTFul服务
    Java多线程中的异常处理
    Checked异常和Runtime异常体系
    hql 语法与详细解释<转>
    hibernate实现有两种配置,xml配置与注释配置。<转>
    Hibernate配置详细解释
    重构(Refactoring)技巧读书笔记(General Refactoring Tips)
    Hibernate(1)——数据访问层的架构模式<转>
    关于layer.photos即照片显示的问题。
  • 原文地址:https://www.cnblogs.com/natian-ws/p/10201052.html
Copyright © 2011-2022 走看看