[java] Thread类详解

本文详细解析了Java中的Thread类,包括其重要成员变量、构造方法、start()、run()、sleep()、yield()、interrupt()等方法的使用及区别。讨论了直接调用run()与start()的不同,线程状态的获取,以及为什么wait和notify方法不在Thread类中定义。通过对Thread类的深入理解,有助于更好地掌握Java多线程编程。
摘要由CSDN通过智能技术生成

 

Table of Contents

概述

Thread类中的重要成员变量

Thread类中的方法分析

构造方法

start方法

run方法

问题:Thread直接调用run()和start()方法的区别?

sleep方法

yield方法

interrupt方法

join方法

getState方法

holdsLock方法判断线程是否持有锁对象

获取当前线程

设置线程优先级

设置和获取线程名字

守护线程

获取一个线程的栈轨迹

问题:为什么wait和notify方法不在Thread类里定义?

总结


本篇博客基于jdk1.8

概述

Thread的一个实例,即是一个程序中执行的一个线程,java虚拟机允许一个应用程序同时有多个并发的线程运行。

每一个线程都有一个优先级。优先级高的线程比优先级低的线程优先执行。每一个线程也都可能被标记为一个守护线程。当代码执行到某一个线程去创建另一个线程时,新创建的线程的优先级会初始化成和创建它的线程一样。并且当且仅当创建线程为守护线程时,被创建线程才会被设为守护线程。

当Java虚拟机启动时,通常会有一个单独的非守护进程线程(通常这个非守护线程会去调用一个指定的类的main方法)。Java虚拟机器继续执行线程,直到以下任一一种情况发生:

Runtime类的exit方法被调用并且security manager(安全管理器)允许退出操作操作发生。

所有的非守护线程全部都已经终结,要么通过从调用返回到运行方法或由抛出超出运行的异常方法。

创建一个新的执行线程有两种方法:

声明一个Thread类的子类。这个子类应当去重写Thread类里的run方法。然后子类的实例就可以分配和启动。例如,计算大于指定值的素数的线程可以写成如下:

class PrimeThread extends Thread {
          long minPrime;
          PrimeThread(long minPrime) {
              this.minPrime = minPrime;
          }
 
          public void run() {
              // compute primes larger than minPrime
              ...
          }
}

下面的代码就可以创建一个线程并启动它:

PrimeThread p = new PrimeThread(143);
p.start();

创建线程的另一种方法是声明一个类实现Runable接口,这个类需要实现run方法,然后这个类的实例就可以在创建线程时被当做参数传递进去,并且启动,同一个例子的另一种样式如下:

class PrimeRun implements Runnable {
          long minPrime;
          PrimeRun(long minPrime) {
              this.minPrime = minPrime;
          }
 
          public void run() {
              // compute primes larger than minPrime
              ...
          }
}

然后,下面的代码就可以创建一个线程并启动它:

PrimeRun p = new PrimeRun(143);
new Thread(p).start();

每个线程都有用于标识目的的名称。多个线程可能具有相同的名称。如果创建一个线程时未指定名称,则会为其生成一个新名称。

除非另有说明,否则,向Thread类中的构造函数或方法传递null参数将导致抛出NullPointerException。

另外一点特别有意思的是,Thread类本身就是实现了Runnable接口的一个类。

Thread类中的重要成员变量

    private volatile String name;   //线程的名字
    private int priority; //线程优先级
    /* Whether or not to single_step this thread. */
    private boolean     single_step;

    /* Whether or not the thread is a daemon thread. */
    private boolean     daemon = false; //是否是守护线程

    /* What will be run. */
    private Runnable target; //将会被执行的Runnable.

    /* The group of this thread */
    private ThreadGroup group;  //这个线程的组

    /* The context ClassLoader for this thread */
    private ClassLoader contextClassLoader; //这个线程的上下文

    /* The inherited AccessControlContext of this thread */
    private AccessControlContext inheritedAccessControlContext; //继承的请求控制

    /* For autonumbering anonymous threads. */
    private static int threadInitNumber;  //默认线程的自动编号
   
    /* ThreadLocal values pertaining to this thread. This map is maintained
     * by the ThreadLocal class. */
    ThreadLocal.ThreadLocalMap threadLocals = null; //当前线程附属的ThreadLocal,而ThreadLocalMap会被ThreadLocal维护)

    /*
     * InheritableThreadLocal values pertaining to this thread. This map is
     * maintained by the InheritableThreadLocal class.
     */
    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
  // 主要作用:为子线程提供从父线程那里继承的值
  //在创建子线程时,子线程会接收所有可继承的线程局部变量的初始值,以获得父线程所具有的值
  // 创建一个线程时如果保存了所有 InheritableThreadLocal 对象的值,那么这些值也将自动传递给子线程
  //如果一个子线程调用 InheritableThreadLocal 的 get() ,那么它将与它的父线程看到同一个对象

    /*
     * The requested stack size for this thread, or 0 if the creator did
     * not specify a stack size.  It is up to the VM to do whatever it
     * likes with this number; some VMs will ignore it.
     */
    private long stackSize; //该线程请求的堆栈大小 默认一般都是忽略

    /*
     * Thread ID
     */
    private long tid;  // 每个线程都有专属ID,但名字可能重复

    /* For generating thread ID */
    private static long threadSeqNumber;   //用来生成thread ID

    /* Java thread status for tools,
     * initialized to indicate thread 'not yet started'
     */

    private volatile int threadStatus = 0;  //标识线程状态,默认是线程未启动

    /* The object in which this thread is blocked in an interruptible I/O
     * operation, if any.  The blocker's interrupt method should be invoked
     * after setting this thread's interrupt status.
     */
    private volatile Interruptible blocker;  //阻塞器锁,主要用于处理阻塞情况 

    /**
     * The minimum priority that a thread can have.
     */
    public final static int MIN_PRIORITY = 1;//线程的优先级中最小的

   /**
     * The default priority that is assigned to a thread.
     */
    public final static int NORM_PRIORITY = 5; //线程的优先级中第二的同时也是默认的优先级

    /**
     * The maximum priority that a thread can have.
     */
    public final static int MAX_PRIORITY = 10; //最高的优先级

Thread类中的方法分析

构造方法

据完全统计,Thread类里一共提供了九个构造方法...其中有一个是非public的方法。

但是这九个构造方法事实上最后都是调用了一个叫做init的方法,该方法定义如下:


                
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值