Thread

1.创建线程

  1. 继承Thread类
  2. 实现Runnable接口或者Callable接口
  3. 通过线程池
public static void main(String[] args) {
    //创建线程1
    new Thread(
            () -> System.out.println(Thread.currentThread().getName())
    ).start();
    //创建线程2
    new Thread(new MyThread()).start();
    //创建线程3
    ExecutorService singleThreadPool = new ThreadPoolExecutor(1, 1, 0L,
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(1024),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy());
    singleThreadPool.execute(
            () -> System.out.println(Thread.currentThread().getName())
    );
    singleThreadPool.shutdown();
}

static class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}

2.源码分析

1.创建线程

new Thread(
        () -> System.out.println(Thread.currentThread().getName())
).start();

new Thread进入构造函数:

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

这里调用nextThreadNum方法生成一个自增id,再加上Thread作为线程名字

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

之后调用init方法:

private void init(ThreadGroup g, Runnable target, String name,
                  long stackSize) {
    init(g, target, name, stackSize, null, true);
}

接着调用6个参数的init方法:

主要的操作有:

设置线程名称,设置线程组(父线程默认是当前线程,默认线程所属组为父线程组),获取优先级和是否是后台进程,最后保存传入的Runnable的run方法到target

private void init(ThreadGroup g, Runnable target, String name,
                  long stackSize, AccessControlContext acc,
                  boolean inheritThreadLocals) {
    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 (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();
}

2.启动线程

首先判断线程状态,然后将其放入线程组,最后调用start0(native方法)启动线程,如果启动失败从线程组中移除

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".
     */
    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. */
    group.add(this);

    boolean started = false;
    try {
        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 */
        }
    }
}

启动完成后,会调用run方法:

@Override
public void run() {
    if (target != null) {
        target.run();
    }
}

posted @ 2020-09-02 21:57  马晟  阅读(458)  评论(0编辑  收藏  举报