• 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();
        }
    }
    

  • 相关阅读:
    双屏显示器
    Cheat Engine Tutorial v3翻译Cheat Engine 6.1 tutorial(3)
    [转]VC6创建UNICODE版Windows程序
    fread
    [转]回调函数在MFC中的使用
    [转]C++ 虚函数表解析
    [转]C/C++返回内部静态成员的陷阱
    [转]EVC 中 include 的错误
    【rgw压缩】
    【ceph | 运维】rgw重置
  • 原文地址:https://www.cnblogs.com/jordan95225/p/13604724.html
Copyright © 2020-2023  润新知