Thread类

随时随地阅读更多技术实战干货,获取项目源码、学习资料,请关注源代码社区公众号(ydmsq666)

一、类声明:

public class Thread extends Object implements Runnable

二、理解:

Thread表示程序中的执行线程。Java虚拟机允许应用程序并发地运行多个线程。每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。每个线程都可以或不可以标记为一个守护程序。当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序。

当 Java 虚拟机启动时,通常都会有单个非守护线程(它通常会调用某个指定类的 main 方法)。Java 虚拟机会继续执行线程,直到下列任一情况出现时为止:

  • 调用了 Runtime 类的 exit 方法,并且安全管理器允许退出操作发生。
  • 非守护线程的所有线程都已停止运行,无论是通过从对 run 方法的调用中返回,还是通过抛出一个传播到 run 方法之外的异常。

    每个线程都有一个标识名,多个线程可以同名。如果线程创建时没有指定标识名,就会为其生成一个新名称。

    三、嵌套类:

    1、Thread.State   线程状态的类。

    2、Thread.UncaughtExceptionHandler   是一个接口,当 Thread 因未捕获的异常而突然终止时,调用处理程序的接口。

    四、字段摘要:

    1、public static final int MIN_PRIORITY   线程可以具有的最低优先级。

    2、public static final int NORM_PRIORITY  分配给线程的默认优先级。

    3、public static final int MAX_PRIORITY  线程可以具有的最高优先级。

    五、构造方法:

    1、public Thread()        分配新的 Thread 对象。

    这种构造方法与 Thread(null, null, gname) 具有相同的作用,其中 gname 是一个新生成的名称。自动生成的名称的形式为 "Thread-"+n,其中的 n 为整数。

    2、public Thread(Runnable target)      分配新的 Thread 对象。

    这种构造方法与 Thread(null, target,gname) 具有相同的作用,其中的 gname 是一个新生成的名称。自动生成的名称的形式为 “Thread-”+n,其中的 n 为整数。

    3、public Thread(ThreadGroup group,Runnable target)     分配新的 Thread 对象。

    这种构造方法与 Thread(group, target, gname) 具有相同的作用,其中的 gname 是一个新生成的名称。自动生成的名称的形式为 "Thread-"+n ,其中的 n 为整数。

    参数:group - 线程组。

    抛出:SecurityException - 如果当前线程无法在指定的线程组中创建线程。

    4、public Thread(String name)  分配新的 Thread 对象。这种构造方法与 Thread(null, null, name) 具有相同的作用。

    5、public Thread(ThreadGroup group, String name)  分配新的 Thread 对象。这种构造方法与 Thread(group, null, name) 具有相同的作用。

    6、public Thread(Runnable target, String name)  分配新的 Thread 对象。这种构造方法与 Thread(null, target, name) 具有相同的作用。

    7、public Thread(ThreadGroup group, Runnable target, String name)  分配新的 Thread 对象。

    以便将 target 作为其运行对象,将指定的 name 作为其名称,并作为 group 所引用的线程组的一员。

    如果 groupnull,并且有安全管理器,则该组由安全管理器的 getThreadGroup 方法确定。如果 groupnull,并且没有安全管理器,或安全管理器的 getThreadGroup 方法返回 null,则该组与创建新线程的线程被设定为相同的 ThreadGroup。

    如果有安全管理器,则其 checkAccess 方法通过 ThreadGroup 作为其参数被调用。

    此外,当被重写 getContextClassLoadersetContextClassLoader 方法的子类构造方法直接或间接调用时,其 checkPermission 方法通过 RuntimePermission("enableContextClassLoaderOverride") 权限调用。其结果可能是 SecurityException。

    如果 target 参数不是 null,则 targetrun 方法在启动该线程时调用。如果 target 参数为 null,则该线程的 run 方法在该线程启动时调用。

    新创建线程的优先级被设定为创建该线程的线程的优先级,即当前正在运行的线程的优先级。方法 setPriority 可用于将优先级更改为一个新值。

    当且仅当创建新线程的线程当前被标记为守护线程时,新创建的线程才被标记为守护线程。方法 setDaemon 可用于改变线程是否为守护线程。

    参数:group - 线程组。

    target - 其 run 方法被调用的对象。

    name - 新线程的名称。

    抛出:SecurityException - 如果当前线程无法在指定的线程组中创建线程,或者无法重写上下文类加载器方法。

    8、public Thread(ThreadGroup group, Runnable target,String name, long stackSize)  此构造方法可以指定堆栈大小,即虚拟机要为该线程堆栈分配的地址空间的近似字节数。stackSize 参数(如果有)的作用具有高度的平台依赖性。其余的和上面一样。

    在某些平台上,指定一个较高的 stackSize 参数值可能使线程在抛出 StackOverflowError 之前达到较大的递归深度。同样,指定一个较低的值将允许较多的线程并发地存在,且不会抛出 OutOfMemoryError(或其他内部错误)。stackSize 参数的值与最大递归深度和并发程度之间的关系细节与平台有关。在某些平台上,stackSize 参数的值无论如何不会起任何作用。

    作为建议,可以让虚拟机自由处理 stackSize 参数。如果指定值对于平台来说过低,则虚拟机可能使用某些特定于平台的最小值;如果指定值过高,则虚拟机可能使用某些特定于平台的最大值。同样,虚拟机还会视情况自由地舍入指定值(或完全忽略它)。如果stackSize为0则和上面方法具有一样作用。

    由于这种构造方法的行为具有平台依赖性,因此在使用它时要非常小心。执行特定计算所必需的线程堆栈大小可能会因 JRE 实现的不同而不同。鉴于这种不同,仔细调整堆栈大小参数可能是必需的,而且可能要在支持应用程序运行的 JRE 实现上反复调整。

    六、方法详细:

    1、public static Thread currentThread()   返回对当前正在执行的线程对象的引用。

    2、public static void yield()   暂停当前正在执行的线程对象,并执行其他线程。

    3、public static void sleep(long millis) throws InterruptedException   在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权。

    参数: millis - 以毫秒为单位的休眠时间。

    抛出: InterruptedException - 如果任何线程中断了当前线程。当抛出该异常时,当前线程的中断状态 被清除。

     

    4、public static void sleep(long millis,  int nanos)  throws InterruptedException  在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权。

    参数:millis - 以毫秒为单位的休眠时间。

    nanos - 要休眠的另外 0-999999 纳秒。

    抛出:IllegalArgumentException - 如果 millis 值为负或 nanos 值不在 0-999999 范围内。

    InterruptedException - 如果任何线程中断了当前线程。当抛出该异常时,当前线程的中断状态 被清除。

     

    5、public void start()  

    使该线程开始执行;Java 虚拟机调用该线程的 run 方法。

    结果是两个线程并发地运行;当前线程(从调用返回给 start 方法)和另一个线程(执行其 run 方法)。

    多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。

    抛出: IllegalThreadStateException - 如果线程已经启动。

    6、public void run()   如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。

    Thread 的子类应该重写该方法。

    指定者:接口 Runnable 中的 run

    7、public final void stop()  已过时。 该方法具有固有的不安全性。用 Thread.stop 来终止线程将释放它已经锁定的所有监视器(作为沿堆栈向上传播的未检查 ThreadDeath 异常的一个自然后果)。如果以前受这些监视器保护的任何对象都处于一种不一致的状态,则损坏的对象将对其他线程可见,这有可能导致任意的行为。stop 的许多使用都应由只修改某些变量以指示目标线程应该停止运行的代码来取代。目标线程应定期检查该变量,并且如果该变量指示它要停止运行,则从其运行方法依次返回。如果目标线程等待很长时间(例如基于一个条件变量),则应使用 interrupt 方法来中断该等待。

    强迫线程停止执行。

    如果安装了安全管理器,则以 this 作为其参数调用 checkAccess 方法。这可能引发 SecurityException(在当前线程中)。

    如果该线程不同于当前线程(即当前线程试图终止除它本身以外的某一线程),则安全管理器的 checkPermission 方法(带有 RuntimePermission("stopThread") 参数)也会被调用。这会再次抛出 SecurityException(在当前线程中)。

    无论该线程在做些什么,它所代表的线程都被迫异常停止,并抛出一个新创建的 ThreadDeath 对象,作为异常。

    停止一个尚未启动的线程是允许的。如果最后启动了该线程,它会立即终止。

    应用程序通常不应试图捕获 ThreadDeath,除非它必须执行某些异常的清除操作(注意,抛出 ThreadDeath 将导致 try 语句的 finally 子句在线程正式终止前执行)。如果 catch 子句捕获了一个 ThreadDeath 对象,则重新抛出该对象很重要,因为这样该线程才会真正终止。

    对其他未捕获的异常作出反应的顶级错误处理程序不会打印输出消息,或者另外通知应用程序未捕获到的异常是否为 ThreadDeath 的一个实例。

    抛出: SecurityException - 如果当前线程不能修改该线程。

    8、public final void stop(Throwable obj)  已过时。 该方法具有固有的不安全性。

    强迫线程停止执行。

    如果安装了安全管理器,则调用该线程的 checkAccess 方法,这可能引发 SecurityException(在当前线程中)。

    如果该线程不同于当前线程(即当前线程试图终止除它本身以外的某一线程),或者 obj 不是 ThreadDeath 的一个实例,则安全管理器的 checkPermission 方法(带有 RuntimePermission("stopThread") 参数)也会被调用。此外,这可能抛出 SecurityException(在当前线程中)。

    如果参数 obj 为 null,则抛出 NullPointerException(在当前线程中)。

    无论该线程在做些什么,它所代表的线程都被迫异常停止,并抛出 Throwable 对象 obj,作为一个异常。这是一种不正常的操作,通常情况下,应使用不带任何参数的 stop 方法。

    停止一个尚未启动的线程是允许的。如果最后启动了该线程,它会立即终止。

    参数: obj - 要抛出的可抛出对象。

    抛出:SecurityException - 如果当前线程不能修改该线程。

    NullPointerException - 如果 obj 为 null。

    9、public void interrupt()   中断线程。

    如果当前线程没有中断它自己(这在任何情况下都是允许的),则该线程的 checkAccess 方法就会被调用,这可能抛出 SecurityException

    如果线程在调用 Object 类的 wait()wait(long) wait(long, int) 方法,或者该类的 join()join(long)join(long, int)sleep(long)sleep(long, int) 方法过程中受阻,则其中断状态将被清除,它还将收到一个 InterruptedException

    如果该线程在可中断的通道上的 I/O 操作中受阻,则该通道将被关闭,该线程的中断状态将被设置并且该线程将收到一个 ClosedByInterruptException

    如果该线程在一个 Selector 中受阻,则该线程的中断状态将被设置,它将立即从选择操作返回,并可能带有一个非零值,就好像调用了选择器的 wakeup 方法一样。

    如果以前的条件都没有保存,则该线程的中断状态将被设置。

    中断一个不处于活动状态的线程不需要任何作用。

    抛出: SecurityException - 如果当前线程无法修改该线程

    10、public static boolean interrupted()  测试当前线程是否已经中断。线程的中断状态 由该方法清除。换句话说,如果连续两次调用该方法,则第二次调用将返回 false(在第一次调用已清除了其中断状态之后,且第二次调用检验完中断状态前,当前线程再次中断的情况除外)。

    返回:如果当前线程已经中断,则返回 true;否则返回 false

    11、public boolean isInterrupted()   测试线程是否已经中断。线程的中断状态 不受该方法的影响。线程中断被忽略,因为在中断时不处于活动状态的线程将由此返回 false 的方法反映出来。

    返回:如果该线程已经中断,则返回 true;否则返回 false

    12、public void destroy()   已过时。 该方法最初用于破坏该线程,但不作任何清除。它所保持的任何监视器都会保持锁定状态。不过,该方法决不会被实现。即使要实现,它也极有可能以 suspend() 方式被死锁。如果目标线程被破坏时保持一个保护关键系统资源的锁,则任何线程在任何时候都无法再次访问该资源。如果另一个线程曾试图锁定该资源,则会出现死锁。这类死锁通常会证明它们自己是“冻结”的进程。

    13、public final boolean isAlive()   测试线程是否处于活动状态。如果线程已经启动且尚未终止,则为活动状态。

    14、public final void suspend()   挂起线程。 已过时。 该方法已经遭到反对,因为它具有固有的死锁倾向。如果目标线程挂起时在保护关键系统资源的监视器上保持有锁,则在目标线程重新开始以前任何线程都不能访问该资源。如果重新开始目标线程的线程想在调用 resume 之前锁定该监视器,则会发生死锁。这类死锁通常会证明自己是“冻结”的进程。

    首先,调用线程的 checkAccess 方法,且不带任何参数。这可能抛出 SecurityException(在当前线程中)。

    如果线程处于活动状态则被挂起,且不再有进一步的活动,除非重新开始。

    抛出:SecurityException - 如果当前线程不能修改该线程。

    15、public final void resume()  已过时。 该方法只与 suspend() 一起使用,但 suspend() 已经遭到反对,因为它具有死锁倾向。

    重新开始挂起的进程。

    首先,调用线程的 checkAccess 方法,且不带任何参数。这可能抛出 SecurityException(在当前线程中)。

    如果线程处于活动状态但被挂起,则它会在执行过程中重新开始并允许继续活动。

    抛出:SecurityException - 如果当前线程不能修改该线程。

    16、public final void setPriority(int newPriority)    更改线程的优先级。

    首先调用线程的 checkAccess 方法,且不带任何参数。这可能抛出 SecurityException

    在其他情况下,线程优先级被设定为指定的 newPriority 和该线程的线程组的最大允许优先级相比较小的一个。

    抛出:IllegalArgumentException - 如果优先级不在 MIN_PRIORITYMAX_PRIORITY 范围内。

    SecurityException - 如果当前线程无法修改该线程。

     

    17、public final int getPriority()   返回线程的优先级。

    18、public final void setName(String name)  改变线程名称,使之与参数 name 相同。

    首先调用线程的 checkAccess 方法,且不带任何参数。这可能抛出 SecurityException

    抛出:SecurityException - 如果当前线程不能修改该线程。

    19、public final String getName()   返回该线程的名称。

    20、public final ThreadGroup getThreadGroup()   返回该线程所属的线程组。 如果该线程已经终止(停止运行),该方法则返回 null。

    21、public static int activeCount()   返回当前线程的线程组中活动线程的数目。

    22、public static int enumerate(Thread[] tarray)  

    将当前线程的线程组及其子组中的每一个活动线程复制到指定的数组中。该方法只调用当前线程的线程组的 enumerate 方法,且带有数组参数。

    首先,如果有安全管理器,则 enumerate 方法调用安全管理器的 checkAccess 方法,并将线程组作为其参数。这可能导致抛出 SecurityException

    参数:tarray - 要复制到的线程对象数组

    返回:放入该数组的线程数

    抛出:SecurityException - 如果安全管理器存在,并且其 checkAccess 方法不允许该操作。

     

    23、public int countStackFrames() 已过时。 该调用的定义依赖于 suspend(),但它遭到了反对。此外,该调用的结果从来都不是意义明确的。 计算该线程中的堆栈帧数。线程必须挂起。

    返回:该线程中的堆栈帧数。

    抛出:IllegalThreadStateException - 如果该线程未挂起。

    24、public final void join(long millis)  throws InterruptedException  等待该线程终止的时间最长为 millis 毫秒。超时为 0 意味着要一直等下去。

    抛出: InterruptedException - 如果任何线程中断了当前线程。当抛出该异常时,当前线程的中断状态 被清除。

    25、public final void join(long millis,  int nanos)  throws InterruptedException   等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒。

    抛出:IllegalArgumentException - 如果 millis 值为负,则 nanos 的值不在 0-999999 范围内。

    InterruptedException - 如果任何线程中断了当前线程。当抛出该异常时,当前线程的中断状态 被清除。

    26、public final void join() throws InterruptedException  等待该线程终止。

    抛出: InterruptedException - 如果任何线程中断了当前线程。当抛出该异常时,当前线程的中断状态 被清除。

    27、public static void dumpStack()   将当前线程的堆栈跟踪打印至标准错误流。该方法仅用于调试。

    28、public final void setDaemon(boolean on) 

    将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。

    该方法必须在启动线程前调用。

    该方法首先调用该线程的 checkAccess 方法,且不带任何参数。这可能抛出 SecurityException(在当前线程中)。

    抛出:IllegalThreadStateException - 如果该线程处于活动状态。

    SecurityException - 如果当前线程无法修改该线程。

    29、public final boolean isDaemon()  测试该线程是否为守护线程。

    30、public final void checkAccess()  判定当前运行的线程是否有权修改该线程。

    如果有安全管理器,则调用其 checkAccess 方法,并将该线程作为其参数。这可能导致抛出 SecurityException

    抛出:SecurityException - 如果不允许当前线程访问该线程。

    31、toString  public String toString()    返回该线程的字符串表示形式,包括线程名称、优先级和线程组。

    32、public ClassLoader getContextClassLoader()   返回该线程的上下文 ClassLoader。

    上下文 ClassLoader 由线程创建者提供,供运行于该线程中的代码在加载类和资源时使用。如果未设定,则默认为父线程的 ClassLoader 上下文。原始线程的上下文 ClassLoader 通常设定为用于加载应用程序的类加载器。

    首先,如果有安全管理器,并且调用者的类加载器不是 null,也不同于其上下文类加载器正在被请求的线程上下文类加载器的祖先,则通过 RuntimePermission("getClassLoader") 权限调用该安全管理器的 checkPermission 方法,查看是否可以获取上下文 ClassLoader。

    33、public void setContextClassLoader(ClassLoader cl)  设置该线程的上下文 ClassLoader。

    上下文 ClassLoader 可以在创建线程设置,并允许创建者在加载类和资源时向该线程中运行的代码提供适当的类加载器。

    首先,如果有安全管理器,则通过 RuntimePermission("setContextClassLoader") 权限调用其 checkPermission 方法,查看是否可以设置上下文 ClassLoader。

    抛出: SecurityException - 如果当前线程无法设置上下文 ClassLoader。

    34、public static boolean holdsLock(Object obj)   当且仅当当前线程在指定的对象上保持监视器锁时,才返回 true。

    该方法旨在使程序能够断言当前线程已经保持一个指定的锁:  assert Thread.holdsLock(obj);
    参数:obj - 用于测试锁所属权的对象

    返回:如果当前线程在指定的对象上保持监视器锁,则返回 true。

    抛出:NullPointerException - 如果 obj 为 null

    35、public StackTraceElement[] getStackTrace() 

    返回一个表示该线程堆栈转储的堆栈跟踪元素数组。如果该线程尚未启动或已经终止,则该方法将返回一个零长度数组。如果返回的数组不是零长度的,则其第一个元素代表堆栈顶,它是该序列中最新的方法调用。最后一个元素代表堆栈底,是该序列中最旧的方法调用。

    如果有安全管理器,并且该线程不是当前线程,则通过 RuntimePermission("getStackTrace") 权限调用安全管理器的 checkPermission 方法,查看是否可以获取堆栈跟踪。

    某些虚拟机在某些情况下可能会从堆栈跟踪中省略一个或多个堆栈帧。在极端情况下,没有该线程堆栈跟踪信息的虚拟机可以从该方法返回一个零长度数组。

    返回:StackTraceElement 数组,每个数组代表一个堆栈帧。

    抛出:SecurityException - 如果安全管理器存在,并且其 checkPermission 方法不允许获取线程的堆栈跟踪。

    36、public static Map<Thread,StackTraceElement[]> getAllStackTraces() 

    返回所有活动线程的堆栈跟踪的一个映射。映射键是线程,而每个映射值都是一个 StackTraceElement 数组,该数组表示相应 Thread 的堆栈转储。返回的堆栈跟踪的格式都是针对 getStackTrace 方法指定的。

    在调用该方法的同时,线程可能也在执行。每个线程的堆栈跟踪仅代表一个快照,并且每个堆栈跟踪都可以在不同时间获得。如果虚拟机没有线程的堆栈跟踪信息,则映射值中将返回一个零长度数组。

    如果有安全管理器,则通过 RuntimePermission("getStackTrace") 权限和 RuntimePermission("modifyThreadGroup") 权限调用其 checkPermission 方法,查看是否可以获取所有线程的堆栈跟踪。

    返回:从 Thread 到 StackTraceElement 数组的一个 Map,代表相应线程的堆栈跟踪。

    抛出:SecurityException - 如果安全管理器存在,并且其 checkPermission 方法不允许获取线程的堆栈跟踪。

    37、public long getId()  返回该线程的标识符。线程 ID 是一个正的 long 数,在创建该线程时生成。线程 ID 是唯一的,并终生不变。线程终止时,该线程 ID 可以被重新使用。

    38、public Thread.State getState()   返回该线程的状态。 该方法用于监视系统状态,不用于同步控制。

    39、public static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)

     设置当线程由于未捕获到异常而突然终止,并且没有为该线程定义其他处理程序时所调用的默认处理程序。

    未捕获到的异常处理首先由线程控制,然后由线程的 ThreadGroup 对象控制,最后由未捕获到的默认异常处理程序控制。如果线程不设置明确的未捕获到的异常处理程序,并且该线程的线程组(包括父线程组)未特别指定其 uncaughtException 方法,则将调用默认处理程序的 uncaughtException 方法。

    通过设置未捕获到的默认异常处理程序,应用程序可以为那些已经接受系统提供的任何“默认”行为的线程改变未捕获到的异常处理方式(如记录到某一特定设备或文件)。

    请注意,未捕获到的默认异常处理程序通常不应顺从该线程的 ThreadGroup 对象,因为这可能导致无限递归。

    参数:eh - 用作未捕获到的默认异常处理程序的对象。 如果为 null,则没有默认处理程序。

    抛出:SecurityException - 如果安全管理器存在并拒绝 RuntimePermission ("setDefaultUncaughtExceptionHandler")

    40、public static Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler()  返回线程由于未捕获到异常而突然终止时调用的默认处理程序。如果返回值为 null,则没有默认处理程序。

    41、public Thread.UncaughtExceptionHandler getUncaughtExceptionHandler()  返回该线程由于未捕获到异常而突然终止时调用的处理程序。如果该线程尚未明确设置未捕获到的异常处理程序,则返回该线程的 ThreadGroup 对象,除非该线程已经终止,在这种情况下,将返回 null。

    42、public void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)  设置该线程由于未捕获到异常而突然终止时调用的处理程序。

    通过明确设置未捕获到的异常处理程序,线程可以完全控制它对未捕获到的异常作出响应的方式。如果没有设置这样的处理程序,则该线程的 ThreadGroup 对象将充当其处理程序。

    参数: eh - 用作该线程未捕获到的异常处理程序的对象。如果为 null,则该线程没有明确的处理程序。

    抛出: SecurityException - 如果当前线程无权修改该线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值