本文来自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的作用

Java中Thread源码剖析的更多相关文章

  1. 【java集合框架源码剖析系列】java源码剖析之TreeSet

    本博客将从源码的角度带领大家学习TreeSet相关的知识. 一TreeSet类的定义: public class TreeSet<E> extends AbstractSet<E&g ...

  2. 【java集合框架源码剖析系列】java源码剖析之HashSet

    注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本.本博客将从源码角度带领大家学习关于HashSet的知识. 一HashSet的定义: public class HashSet&l ...

  3. 【java集合框架源码剖析系列】java源码剖析之TreeMap

    注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本.本博客将从源码角度带领大家学习关于TreeMap的知识. 一TreeMap的定义: public class TreeMap&l ...

  4. 【java集合框架源码剖析系列】java源码剖析之ArrayList

    注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本. 本博客将从源码角度带领大家学习关于ArrayList的知识. 一ArrayList类的定义: public class Arr ...

  5. 【java集合框架源码剖析系列】java源码剖析之LinkedList

    注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本. 在实际项目中LinkedList也是使用频率非常高的一种集合,本博客将从源码角度带领大家学习关于LinkedList的知识. ...

  6. 【java集合框架源码剖析系列】java源码剖析之HashMap

    前言:之所以打算写java集合框架源码剖析系列博客是因为自己反思了一下阿里内推一面的失败(估计没过,因为写此博客已距阿里巴巴一面一个星期),当时面试完之后感觉自己回答的挺好的,而且据面试官最后说的这几 ...

  7. 我的书籍《深入解析Java编译器:源码剖析与实例详解》就要出版了

    一个十足的技术迷,2013年毕业,做过ERP.游戏.计算广告,在大公司呆过,但终究不满足仅对技术的应用,在2018年末离开了公司,全职写了一本书<深入解析Java编译器:源码剖析与实例详解> ...

  8. 【java集合框架源码剖析系列】java源码剖析之java集合中的折半插入排序算法

    注:关于排序算法,博主写过[数据结构排序算法系列]数据结构八大排序算法,基本上把所有的排序算法都详细的讲解过,而之所以单独将java集合中的排序算法拿出来讲解,是因为在阿里巴巴内推面试的时候面试官问过 ...

  9. Java中ArrayList源码分析

    一.简介 ArrayList是一个数组队列,相当于动态数组.每个ArrayList实例都有自己的容量,该容量至少和所存储数据的个数一样大小,在每次添加数据时,它会使用ensureCapacity()保 ...

随机推荐

  1. unity C# 获取有关文件、文件夹和驱动器的信息

    class FileSysInfo { static void Main() { // You can also use System.Environment.GetLogicalDrives to ...

  2. python中的类与继承

    Class 类的定义以及实例的建立 Python中,类通过 class 关键字定义. 例如最简单的一个类定义可以为: class Person(object): pass Python 的编程习惯,类 ...

  3. Hadoop学习总结(1)——大数据以及Hadoop相关概念介绍

    一.大数据的基本概念 1.1.什么是大数据 大数据指的就是要处理的数据是TB级别以上的数据.大数据是以TB级别起步的.在计算机当中,存放到硬盘上面的文件都会占用一定的存储空间,例如: 文件占用的存储空 ...

  4. Java基础学习总结(18)——网络编程

    一.网络基础概念 首先理清一个概念:网络编程 != 网站编程,网络编程现在一般称为TCP/IP编程. 二.网络通信协议及接口 三.通信协议分层思想 四.参考模型 五.IP协议 每个人的电脑都有一个独一 ...

  5. SPOJ 694 Distinct Substrings

    Distinct Substrings Time Limit: 1000ms Memory Limit: 262144KB This problem will be judged on SPOJ. O ...

  6. POJ——T 3255 Roadblocks|| COGS——T 315. [POJ3255] 地砖RoadBlocks || 洛谷—— P2865 [USACO06NOV]路障Roadblocks

    http://poj.org/problem?id=3255 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15680   ...

  7. hadoop云盘client的设计与实现(一)

    近期在hadoop云盘client项目.在做这个项目曾经对hadoop是一点都不了解呀,在网上查了好久.将client开发的是非常少的,在做这个项目的过程中遇到非常多奇葩的问题. 并且试图换过好多方案 ...

  8. Atitit.软件开发的终于的设计&#160;dsl化,ast化(建立ast,&#160;解析运行ast)

    Atitit.软件开发的终于的设计 dsl化,ast化(建立ast, 解析运行ast) 1. 使用js,html 撰写dsl 1 1.1. 架构图 1 1.2. html 2 1.3. Js 2 1. ...

  9. 热门游戏&lt;开心消消乐&gt;的“加壳”诡计!!

    好久没搞游戏了,前几天看了又又一次看了看<开心消消乐>的1.29最新版..于是故事開始了: 1.反编译分析 首先使用Androidkiller进行反编译,得到两个Smali代码目录:mal ...

  10. Id选择器和Class选择器

    http://www.runoob.com/css/css-id-class.html http://www.w3school.com.cn/css/css_syntax_id_selector.as ...