Thread类源码解析

Java线程创建与管理

该类实现了Runnable接口。有两种方法用于创建线程:

  • 继承Thread类,覆盖run方法
  • 申明该类实现了Runnable接口,覆盖run方法

1.构造方法

thread类一共有9个构造方法,包括8个public构造方法和一个non public构造方法:

public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }
public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }
Thread(Runnable target, AccessControlContext acc) {
        init(null, target, "Thread-" + nextThreadNum(), 0, acc);
    }
public Thread(ThreadGroup group, Runnable target) {
        init(group, target, "Thread-" + nextThreadNum(), 0);
    }
public Thread(String name) {
        init(null, null, name, 0);
    }
public Thread(ThreadGroup group, String name) {
        init(group, null, name, 0);
    }
public Thread(Runnable target, String name) {
        init(null, target, name, 0);
    }
public Thread(ThreadGroup group, Runnable target, String name) {
        init(group, target, name, 0);
    }
public Thread(ThreadGroup group, Runnable target, String name,
                  long stackSize) {
        init(group, target, name, stackSize);
    }

参数涵义:

  • Runnable target:用来指示当新线程启动时,被调用的run方法所属的对象;带有该参数的构造函数支持传入一个Runnable接口的对象
  • AccessControlContext acc:上述包含此参数的构造函数用于创建一个继承了指定AccessControlContext 类的线程
  • String name:线程的名字,用来区分线程
  • ThreadGroup group:线程所属的组
  • long stackSize:新线程所需栈的大小。 该参数的值与最大递归深度和并发度之间的关系,与平台高度相关。虚拟机可以自由将stackSize参数作为建议,自己调整并采用适合平台的值。

从源码中可以看出,所有的构造方法都是通过init()方法实现的

2.其他方法

 

  • public static native Thread currentThread();——返回当前线程的引用
  • public static native void yield();——当前线程提示调度器自己可以暂时放弃CPU使用,但是调度器可以忽略该提示。放弃的时间不确定,有可能刚刚放弃马上又获得CPU时间片,常用于调试或测试目的,另外在设计诸如java.util.concurrent.locks包中的并发控制结构时,可能很有用。
  • public static native void sleep(long millis) throws InterruptedException;——调用该方法使当前执行的线程进入休眠状态,指定休眠时间为millis毫秒,但是该线程不会失去任务监视器的所有权;在参数为负或被其他线程中断的情况下,分别抛出IllegalArgumentException和InterruptedException异常
  • public static void sleep(long millis, int nanos)  throws InterruptedException;——在上一个方法的基础上对休眠时间进行微调
  • protected Object clone() throws CloneNotSupportedException;——该方法是重写Object类的clone方法,克隆一个新的线程;当无法克隆时,抛出CloneNotSupportedException异常
  • public synchronized void start()——使当前线程开始执行,线程调用该方法后,虚拟机会调用该线程的run方法。调用该方法会导致两个线程同时运行:当前线程从start方法返回;另一个线程执行run方法;如果线程早已启动,则会抛出IllegalThreadStateException异常。该方法内部通过执行本地方法start0()来启动线程。
  • private native void start0();
  • public void run();——如果当前线程时使用Runnable对象构造的,那么该run方法内部实际上是调用的Runnable对象的run方法;Thread类的子类应该重写该方法
  • public void interrupt()——中断这个线程(即调用该方法的这个线程),仅仅是在当前线程中打了一个停止的标记,并不是真的停止线程。该方法的内部在同步代码块中设置了一个阻塞标志
  • public static boolean interrupted()——测试当前线程是否被中断(如果被中断返回true,否则返回false),同时会清除线程的“中断状态”意思是如果连续调用两次该函数,则第二次调用的结果为false,除非在第一次调用后,第二次调用前当前线程被再次中断。同样,如果线程在被中断时处于not alive状态,则仍然返回false。该方法是通过调用isInterrupted()方法实现的。注意该方法为静态方法,Thread类可以直接调用。
  • public boolean isInterrupted()——测试线程是否被中断(这里的线程指Thread对象),中断线程状态不受该方法的影响,即不会清除状态标志
  • private native boolean isInterrupted(boolean ClearInterrupted);——上面两个方法本质上都是通过该本地方法实现的
  • public final native boolean isAlive()——测试当前线程是否存活(存活返回true,否则返回false)。存活的标志是线程已经被启动并且没有死亡
  • public final synchronized void join(long millis)  throws InterruptedException——内部使用wait(long)方法实现,所以该方法具有释放锁的特点
  • public final synchronized void join(long millis, int nanos) throws InterruptedException——
  •  public final void join() throws InterruptedException——使所属的线程对象X正常执行run()方法,而使当前线程Z进行无限期的阻塞,等待线程X销毁后再继续执行线程Z后面的代码
  • public String toString()——返回表示该线程的一个字符串,内容包括:线程的名称+优先级+所属的组
  • public long getId()——取得线程的ID。该ID是long型,在线程的整个生命过程中,ID不变,当线程终止后,该ID可以重新使用
  • public final void checkAccess()——该方法决定当前正在运行的线程是否有权修改this thread(这个的this thread代表自身类的对象,即Thread类的对象)。如果现在有安全管理器,则调用该安全管理器的checkAccess方法,并把this thread作为传输参数,如果当前线程不被允许访问this thread,则抛出SecurityException异常。
  • public final void setPriority(int newPriority)——将this thread的优先级设置为(newPriority和线程组允许的最大优先级)中的较小者,Java中,最大优先为10,最小优先级为1,标准值为5。如果newPriority大于1或小于10,则会抛出IllegalArgumentException异常。该方法内部首先调用了checkAccess方法,因此可能会抛出SecurityException异常。该方法设置为final,说明子类会继承父类的优先级。高优先级的线程在概率上而言,大部分会先执行完,但是线程的优先级具有“随机性”,也就是优先级较高的线程不一定每一次都先执行完。总之,线程优先级与打印顺序无关。
  • public final void setDaemon(boolean on)——将this thread标记为守护线程或用户线程,on==true,则为守护线程,否则,为用户线程。 当只有运行的线程都是守护进程线程时,Java虚拟机才会退出。该方法必须在线程启动之前调用,因此调用该方法时,如果这个线程处于“存活”状态,则会抛出IllegalThreadStateException异常。

上述方法中,内部调用了checkAccess()方法的方法,都会作用于Thread的类对象,即this thread。

什么是守护线程?

在Java线程中有两种线程,一种是用户线程,另一种是守护线程。守护线程是一种特殊的线程,它的特性有“陪伴”的含义,当进程中不存在非守护线程了,则守护线程自动销毁。典型的守护线程就是垃圾回收线程。只要当前JVM实例中存在任何一个非守护线程没有结束,守护线程就在工作,只有当最后一个非守护线程结束时,守护线程才随着JVM一同结束工作。Daemon的作用是为其他线程的运行提供便利服务,守护线程最典型的应用就是GC。

3.例子

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值