zoukankan      html  css  js  c++  java
  • Java中Thread源码剖析


                                           本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处!


    关于线程,用很长时间了,主线程下的子线程去做一些事情,就是一个代理模式,主线程分代理权给子线程,子线程帮主线程完成一些任务。

    线程的方法大部分都是使用Native使用,不允许应用层修改,是CPU调度的最基本单元。实现线程的方式有三种:使用内核线程、用户线程和混合线程来实现,奉行先行发生的原则。

    内核线程:每个生成的线程,都1:1配比一个内核线程来支持,即双线程机制,消耗一个内核资源,类似手机中应用进程

    用户线程:普通线程,高速且低耗,创建、切换、调度等问题都需要自己处理

    混合实现:降低被阻塞的风险,用户线程与内核线程相当于M:N的关系

    线程的调度方式主要有两种:协同式和抢占式,前者简单但不可控制,一个线程执行完通知另外一个;抢占式可以通过yield方法让出执行时间,Java目前就采用这种,同时可以使用设置优先级的方式来提前线程执行顺序,但有可能被“系统”关闭。


    今天我们来看下线程的源码,进行系统的学习。

    1、首先线程有六种状态

        public enum State {
            /**
             * The thread has been created, but has never been started.
             */
            NEW,
            /**
             * The thread may be run.
             */
            RUNNABLE,
            /**
             * The thread is blocked and waiting for a lock.
             */
            BLOCKED,
            /**
             * The thread is waiting.
             */
            WAITING,
            /**
             * The thread is waiting for a specified amount of time.
             */
            TIMED_WAITING,
            /**
             * The thread has been terminated.
             */
            TERMINATED
        }

    NEW:刚创建还没启动

    RUNNABLE:可以执行 

    BLOCKED:堵塞状态,等待持有锁

    WAITING :处理等待状态 

    TIMED_WAITING:等待一些时间

    TERMINATED:终止

        /**
         * The maximum priority value allowed for a thread.
         */
        public static final int MAX_PRIORITY = 10;


        /**
         * The minimum priority value allowed for a thread.
         */
        public static final int MIN_PRIORITY = 1;


        /**
         * The normal (default) priority value assigned to threads.
         */
        public static final int NORM_PRIORITY = 5;

    2、分别是线程可设置的最大、最小和默认优先级,级别越高执行越靠前

        /**
         * Holds the thread's ID. We simply count upwards, so
         * each Thread has a unique ID.
         */
        private long id;

    3、每个线程都有一个独一无二的ID

    public Thread() {
            create(null, null, null, 0);
        }

     private void create(ThreadGroup group, Runnable runnable, String threadName, long stackSize) {
            Thread currentThread = Thread.currentThread();
            if (group == null) {
                group = currentThread.getThreadGroup();
            }


            if (group.isDestroyed()) {
                throw new IllegalThreadStateException("Group already destroyed");
            }


            this.group = group;


            synchronized (Thread.class) {
                id = ++Thread.count;
            }


            if (threadName == null) {
                this.name = "Thread-" + id;
            } else {
                this.name = threadName;
            }


            this.target = runnable;
            this.stackSize = stackSize;


            this.priority = currentThread.getPriority();


            this.contextClassLoader = currentThread.contextClassLoader;


            // Transfer over InheritableThreadLocals.
            if (currentThread.inheritableValues != null) {
                inheritableValues = new ThreadLocal.Values(currentThread.inheritableValues);
            }
            // add ourselves to our ThreadGroup of choice
            this.group.addThread(this);
        }

    4、初始化一个空的线程,获得当前运行的线程群组,设置id,name,执行线程runnable,池大小stackSize,优先级,并加入到线程群组,这是一个无参的Thread,正常情况下应该有ThreadGroup、Runnable、threadName和stackSize这四个参数。一般threadName如果为空,则报出NullPointerException,stackSize默认为0。

        /**
         * Destroys the receiver without any monitor cleanup.
         *
         * @deprecated Not implemented.
         */
        @Deprecated
        public void destroy() {
            throw new NoSuchMethodError("Thread.destroy()"); // TODO Externalize???
        }

    5、destroy方法在java7已经被抛弃。

        public void interrupt() {
            synchronized (interruptActions) {
                for (int i = interruptActions.size() - 1; i >= 0; i--) {
                    interruptActions.get(i).run();
                }
            }

            VMThread vmt = this.vmThread;
            if (vmt != null) {
                vmt.interrupt();
            }
        }

    6、停止当前线程,如果线程处于wait、join、sleep状态的线程,会报异常。

      public final boolean isAlive() {
            return (vmThread != null);
        }

    7、线程是否死掉,主要是判断虚拟机线程有没有死掉VMThread,当然获得当前线程也是通过VMThread.currentThread(),以及接下下获得当前线程处于六大状态中的哪种。

        public State getState() {
            // TODO This is ugly and should be implemented better.
            VMThread vmt = this.vmThread;


            // Make sure we have a valid reference to an object. If native code
            // deletes the reference we won't run into a null reference later.
            VMThread thread = vmThread;
            if (thread != null) {
                // If the Thread Object became invalid or was not yet started,
                // getStatus() will return -1.
                int state = thread.getStatus();
                if(state != -1) {
                    return VMThread.STATE_MAP[state];
                }
            }
            return hasBeenStarted ? Thread.State.TERMINATED : Thread.State.NEW;
        }

     public final void join() throws InterruptedException {
            VMThread t = vmThread;
            if (t == null) {
                return;
            }


            synchronized (t) {
                while (isAlive()) {
                    t.wait();
                }
            }
        }

    8、join堵塞当前线程,使其处于等待状态,因为子线程执行的时间可能比主线程执行时间还长,所以join是主线程需要在它执行完后再销毁。当然也可以加参数join(long millis, int nanos),使其等待N秒N毫秒,如果它已经处于join方法,则报InterruptedException 。

        public final void setDaemon(boolean isDaemon) {
            if (hasBeenStarted) {
                throw new IllegalThreadStateException("Thread already started."); // TODO Externalize?
            }


            if (vmThread == null) {
                daemon = isDaemon;
            }
        }

    9、设置为守护线程,必须的runnable执行前设置,会在其他已经没有非守护线程运行的时候执行。

        public final void setPriority(int priority) {
            if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
                throw new IllegalArgumentException("Priority out of range"); // TODO Externalize?
            }


            if (priority > group.getMaxPriority()) {
                priority = group.getMaxPriority();
            }


            this.priority = priority;


            VMThread vmt = this.vmThread;
            if (vmt != null) {
                vmt.setPriority(priority);
            }
        }

    10、优先级主要通过VMThread来设置的,注意最高设为10最低为1,否则报 IllegalArgumentException。

       public static void sleep(long millis, int nanos) throws InterruptedException {

            VMThread.sleep(millis, nanos);
        }

    11、执行sleep,如果在sleep期间被interrupt,会报InterruptedException。

        /**
         * Starts the new Thread of execution. The <code>run()</code> method of
         * the receiver will be called by the receiver Thread itself (and not the
         * Thread calling <code>start()</code>).
         *
         * @throws IllegalThreadStateException if the Thread has been started before
         *
         * @see Thread#run
         */
        public synchronized void start() {
            if (hasBeenStarted) {
                throw new IllegalThreadStateException("Thread already started."); // TODO Externalize?
            }


            hasBeenStarted = true;


            VMThread.create(this, stackSize);
        }

    12、线程开始执行,如果start已经执行,则报IllegalThreadStateException

        @Deprecated
        public final synchronized void stop(Throwable throwable) {
            throw new UnsupportedOperationException();
        }

    13、stop方法弃用

    public static void yield() {
            VMThread.yield();
        }

    14、给另一个准备运行的线程让路,让它先执行

    关于join和yield的区别,更在上一节: 

    Java中join和yield的作用



  • 相关阅读:
    课堂作业04 2017.10.27
    课程作业 03 动手动脑 2017.10.20
    课程作业 03 2017.10.20
    HDU 3974 Assign the task
    POJ 2155 Matrix
    POJ 2481 Cows
    HDU 3038 How Many Answers Are Wrong
    CS Academy Array Removal
    POJ_1330 Nearest Common Ancestors LCA
    CF Round 427 D. Palindromic characteristics
  • 原文地址:https://www.cnblogs.com/fengju/p/6174423.html
Copyright © 2011-2022 走看看