Thread学习笔记

01_Thread

线程初始化

  • ThreadGroup:线程组,默认创建线程的线程组
  • Runnable:新建线程时候自己创建的
  • name:线程名,一般是自动创建,格式为:"Thread-" + nextThreadNum(),其中nextThreadNum()为加锁的一个自增数字(synchronized)
  • stackSize:堆栈大小,默认给0

具体的创建逻辑看下面:

        private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
                //1. 如果名字空,直接抛异常,线程怎么可能没有名字呢,开什么玩笑
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }

        this.name = name;
                //2. 这里是获取一下创建该线程的父线程
        Thread parent = currentThread();
        SecurityManager security = System.getSecurityManager();
                //3. 获取一下线程组,如果是空的,就用父线程的线程组
        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;
                //4. 这里设置一下线程优先级,这玩意没啥用,设置了cpu也不会按照他执行
        setPriority(priority);
        if (inheritThreadLocals && 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();
    }

具体的创建线程例子:

Thread thread = new Thread(new Runnable() {
            
            @Override
            public void run() {
                // TODO Auto-generated method stub
                //创建一个线程试一下
            }
});

线程启动

直接看源码:

public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
                //1. 判断一下线程之前启动过没,启动过肯定报错,不能重复启动
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
                //2. 把当前线程放组里面
        group.add(this);

        boolean started = false;
        try {
                        //3. 底层的启动方法
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

sleep是什么

sleep(0)的作用是什么?

sleep会将cpu还给内核,多个线程重新竞争cpu

线程休眠

Thread.sleep(1000)

yield是什么

中断线程,很少使用,尽量别用

join是什么

只有当这个线程执行完才会继续往下走,使用while死循环执行wait,只有当当先线程关闭了,while才会退出循环方法返回

interrupt是什么

  • 功能:优雅退出
  • 有一个标志位会被修改,终止线程

你可能感兴趣的:(java)