Java多线程学习笔记1

多线程学习笔记

在之前的java开发中一般都是java web方向的工作,对多线程使用的非常少。了解仅限于RunnableThread的区别与使用。最近在做小工具的时候用到了多线程,从零开始学习关于多线程和并发方面的知识。

并发和多线程之间的关系

并发与多线程之间的关系就是目的与手段之间的关系。并发(Concurrent)的反面是串行。并发的极致就是并行(Parallel)。多线程就是将原本可能是串行的计算“改为”并发(并行)的一种手段、途径或者模型。因此,有时我们也称多线程编程为并发编程。当然,目的与手段之间常常是一对多的关系。并发编程还有其他的实现途径,多线程编程往往是其他并发编程模型的基础。

实现多线程的方式:1.继承Thread类,2.实现Runnable接口。实际上Thread也是Runnable的一个子类。使用继承Thread最大的局限性在于不支持多继承。所以为了支持多继承,就会使用Runnable接口的方式。
Runnable接口就是定义了一个run方法。所以重点看Thread类。
Thread有9个构造方法。常用的有Thread()Thread(Runnable)两个,构造方法都调用了init()方法,初始化一个线程。

   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.toCharArray();
        Thread parent = currentThread();
        SecurityManager security = System.getSecurityManager();
        if (g == null) {
            /* 判断是否为 applet */
            /* 如果有security manager */
            if (security != null) {
                g = security.getThreadGroup();
            }
            /* 如果 security manager getThreadGroup 为null*/
            if (g == null) {
                g = parent.getThreadGroup();
            }
        }
        /* 不管是否是传入参数的ThreadGroup 都再进行security manager 检查*/
        g.checkAccess();

        /*
         * 权限控制?
         */
        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(ThreadGroup, Runnable, String, stackSize, AccessControlContext)方法来完成Thread对象的创建 整个过程是

  1. registerNatives() 静态块, 判断name。设置name,获取Thread parent ,获取SecurityManager
  2. 检查security .线程组中的nUnstartedThreads++
  3. 设置ThreadGroup线程组,设置daemon是否守护线程,priority优先,ContextClassLoaderclassLoader,inheritedAccessControlContext 继承的访问控制上下文,target为继承Runnable接口的对象。inheritableThreadLocals threadLocal,stackSizeid 设置。
    整个Thread 对象的创建过程大概就是这样一个流程。

你可能感兴趣的:(Java多线程学习笔记1)