java.lang.Object java.lang.Thread
线程 是程序中的执行线程。Java 虚拟机允许应用程序并发地运行多个执行线程。
每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。每个线程都可以或不可以标记为一个守护程序。当某个线程中运行的代码创建一个新 Thread
对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序。
当 Java 虚拟机启动时,通常都会有单个非守护线程(它通常会调用某个指定类的 main
方法)。Java 虚拟机会继续执行线程,直到下列任一情况出现时为止:
Runtime
类的 exit
方法,并且安全管理器允许退出操作发生。 run
方法之外的异常。 创建新执行线程有两种方法。一种方法是将类声明为 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();
创建线程的另一种方法是声明实现 Runnable
接口的类。该类然后实现 run
方法。然后可以分配该类的实例,在创建 Thread
时作为一个参数来传递并启动。采用这种风格的同一个例子如下所示:
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();
每个线程都有一个标识名,多个线程可以同名。如果线程创建时没有指定标识名,就会为其生成一个新名称。
Runnable
,
Runtime.exit(int)
,
run()
,
stop()
嵌套类摘要 | |
---|---|
static class |
Thread.State 线程状态。 |
static interface |
Thread.UncaughtExceptionHandler 当 Thread 因未捕获的异常而突然终止时,调用处理程序的接口。 |
字段摘要 | |
---|---|
static int |
MAX_PRIORITY 线程可以具有的最高优先级。 |
static int |
MIN_PRIORITY 线程可以具有的最低优先级。 |
static int |
NORM_PRIORITY 分配给线程的默认优先级。 |
构造方法摘要 | |
---|---|
Thread() 分配新的 Thread 对象。 |
|
Thread(Runnable target) 分配新的 Thread 对象。 |
|
Thread(Runnable target, String name) 分配新的 Thread 对象。 |
|
Thread(String name) 分配新的 Thread 对象。 |
|
Thread(ThreadGroup group, Runnable target) 分配新的 Thread 对象。 |
|
Thread(ThreadGroup group, Runnable target, String name) 分配新的 Thread 对象,以便将 target 作为其运行对象,将指定的 name 作为其名称,并作为 group 所引用的线程组的一员。 |
|
Thread(ThreadGroup group, Runnable target, String name, long stackSize) 分配新的 Thread 对象,以便将 target 作为其运行对象,将指定的 name 作为其名称,作为 group 所引用的线程组的一员,并具有指定的堆栈大小。 |
|
Thread(ThreadGroup group, String name) 分配新的 Thread 对象。 |
方法摘要 | |
---|---|
static int |
activeCount() 返回当前线程的线程组中活动线程的数目。 |
void |
checkAccess() 判定当前运行的线程是否有权修改该线程。 |
int |
countStackFrames() 已过时。 该调用的定义依赖于 suspend() ,但它遭到了反对。此外,该调用的结果从来都不是意义明确的。 |
static Thread |
currentThread() 返回对当前正在执行的线程对象的引用。 |
void |
destroy() 已过时。 该方法最初用于破坏该线程,但不作任何清除。它所保持的任何监视器都会保持锁定状态。不过,该方法决不会被实现。即使要实现,它也极有可能以 suspend() 方式被死锁。如果目标线程被破坏时保持一个保护关键系统资源的锁,则任何线程在任何时候都无法再次访问该资源。如果另一个线程曾试图锁定该资源,则会出现死锁。这类死锁通常会证明它们自己是“冻结”的进程。有关更多信息,请参阅为何不赞成使用 Thread.stop、Thread.suspend 和 Thread.resume?。 |
static void |
dumpStack() 将当前线程的堆栈跟踪打印至标准错误流。 |
static int |
enumerate(Thread[] tarray) 将当前线程的线程组及其子组中的每一个活动线程复制到指定的数组中。 |
static Map<Thread,StackTraceElement[]> |
getAllStackTraces() 返回所有活动线程的堆栈跟踪的一个映射。 |
ClassLoader |
getContextClassLoader() 返回该线程的上下文 ClassLoader。 |
static Thread.UncaughtExceptionHandler |
getDefaultUncaughtExceptionHandler() 返回线程由于未捕获到异常而突然终止时调用的默认处理程序。 |
long |
getId() 返回该线程的标识符。 |
String |
getName() 返回该线程的名称。 |
int |
getPriority() 返回线程的优先级。 |
StackTraceElement[] |
getStackTrace() 返回一个表示该线程堆栈转储的堆栈跟踪元素数组。 |
Thread.State |
getState() 返回该线程的状态。 |
ThreadGroup |
getThreadGroup() 返回该线程所属的线程组。 |
Thread.UncaughtExceptionHandler |
getUncaughtExceptionHandler() 返回该线程由于未捕获到异常而突然终止时调用的处理程序。 |
static boolean |
holdsLock(Object obj) 当且仅当当前线程在指定的对象上保持监视器锁时,才返回 true。 |
void |
interrupt() 中断线程。 |
static boolean |
interrupted() 测试当前线程是否已经中断。 |
boolean |
isAlive() 测试线程是否处于活动状态。 |
boolean |
isDaemon() 测试该线程是否为守护线程。 |
boolean |
isInterrupted() 测试线程是否已经中断。 |
void |
join() 等待该线程终止。 |
void |
join(long millis) 等待该线程终止的时间最长为 millis 毫秒。 |
void |
join(long millis, int nanos) 等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒。 |
void |
resume() 已过时。 该方法只与 suspend() 一起使用,但 suspend() 已经遭到反对,因为它具有死锁倾向。有关更多信息,请参阅为何不赞成使用 Thread.stop、Thread.suspend 和 Thread.resume?。 |
void |
run() 如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。 |
void |
setContextClassLoader(ClassLoader cl) 设置该线程的上下文 ClassLoader。 |
void |
setDaemon(boolean on) 将该线程标记为守护线程或用户线程。 |
static void |
setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) 设置当线程由于未捕获到异常而突然终止,并且没有为该线程定义其他处理程序时所调用的默认处理程序。 |
void |
setName(String name) 改变线程名称,使之与参数 name 相同。 |
void |
setPriority(int newPriority) 更改线程的优先级。 |
void |
setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) 设置该线程由于未捕获到异常而突然终止时调用的处理程序。 |
static void |
sleep(long millis) 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。 |
static void |
sleep(long millis, int nanos) 在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。 |
void |
start() 使该线程开始执行;Java 虚拟机调用该线程的 run 方法。 |
void |
stop() 已过时。 该方法具有固有的不安全性。用 Thread.stop 来终止线程将释放它已经锁定的所有监视器(作为沿堆栈向上传播的未检查 ThreadDeath 异常的一个自然后果)。如果以前受这些监视器保护的任何对象都处于一种不一致的状态,则损坏的对象将对其他线程可见,这有可能导致任意的行为。stop 的许多使用都应由只修改某些变量以指示目标线程应该停止运行的代码来取代。目标线程应定期检查该变量,并且如果该变量指示它要停止运行,则从其运行方法依次返回。如果目标线程等待很长时间(例如基于一个条件变量),则应使用 interrupt 方法来中断该等待。有关更多信息,请参阅为何不赞成使用 Thread.stop、Thread.suspend 和 Thread.resume?。 |
void |
stop(Throwable obj) 已过时。 该方法具有固有的不安全性。有关详细信息,请参阅 stop() 。 该方法的附加危险是它可用于生成目标线程未准备处理的异常(包括若没有该方法该线程不太可能抛出的已检查的异常)。 有关更多信息,请参阅为何不赞成使用 Thread.stop、Thread.suspend 和 Thread.resume?。 |
void |
suspend() 已过时。 该方法已经遭到反对,因为它具有固有的死锁倾向。如果目标线程挂起时在保护关键系统资源的监视器上保持有锁,则在目标线程重新开始以前任何线程都不能访问该资源。如果重新开始目标线程的线程想在调用 resume 之前锁定该监视器,则会发生死锁。这类死锁通常会证明自己是“冻结”的进程。有关更多信息,请参阅为何不赞成使用 Thread.stop、Thread.suspend 和 Thread.resume?。 |
String |
toString() 返回该线程的字符串表示形式,包括线程名称、优先级和线程组。 |
static void |
yield() 暂停当前正在执行的线程对象,并执行其他线程。 |
从类 java.lang.Object 继承的方法 |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
字段详细信息 |
---|
public static final int MIN_PRIORITY
public static final int NORM_PRIORITY
public static final int MAX_PRIORITY
构造方法详细信息 |
---|
public Thread()
Thread
对象。这种构造方法与
Thread(null, null,
gname
)
具有相同的作用,其中
gname 是一个新生成的名称。自动生成的名称的形式为
"Thread-"+
n,其中的
n 为整数。
public Thread(Runnable target)
Thread
对象。这种构造方法与
Thread(null, target,
gname
)
具有相同的作用,其中的
gname 是一个新生成的名称。自动生成的名称的形式为
“Thread-”+
n,其中的
n 为整数。
target
- 其
run
方法被调用的对象。
Thread(ThreadGroup, Runnable, String)
public Thread(ThreadGroup group, Runnable target)
Thread
对象。这种构造方法与
Thread(group, target,
gname
)
具有相同的作用,其中的
gname 是一个新生成的名称。自动生成的名称的形式为
"Thread-"+
n ,其中的
n 为整数。
group
- 线程组。
target
- 其
run
方法被调用的对象。
SecurityException
- 如果当前线程无法在指定的线程组中创建线程。
Thread(ThreadGroup, Runnable, String)
public Thread(String name)
Thread
对象。这种构造方法与
Thread(null, null, name)
具有相同的作用。
name
- 新线程的名称。
Thread(ThreadGroup, Runnable, String)
public Thread(ThreadGroup group, String name)
Thread
对象。这种构造方法与
Thread(group, null, name)
具有相同的作用。
group
- 线程组。
name
- 新线程的名称。
SecurityException
- 如果当前线程无法在指定的线程组中创建线程。
Thread(ThreadGroup, Runnable, String)
public Thread(Runnable target, String name)
Thread
对象。这种构造方法与
Thread(null, target, name)
具有相同的作用。
target
- 其
run
方法被调用的对象。
name
- 新线程的名称。
Thread(ThreadGroup, Runnable, String)
public Thread(ThreadGroup group, Runnable target, String name)
Thread
对象,以便将
target
作为其运行对象,将指定的
name
作为其名称,并作为
group
所引用的线程组的一员。
如果 group
为 null
,并且有安全管理器,则该组由安全管理器的 getThreadGroup
方法确定。如果 group
为 null
,并且没有安全管理器,或安全管理器的 getThreadGroup
方法返回 null
,则该组与创建新线程的线程被设定为相同的 ThreadGroup。
如果有安全管理器,则其 checkAccess
方法通过 ThreadGroup 作为其参数被调用。
此外,当被重写 getContextClassLoader
或 setContextClassLoader
方法的子类构造方法直接或间接调用时,其 checkPermission
方法通过 RuntimePermission("enableContextClassLoaderOverride")
权限调用。其结果可能是 SecurityException。
如果 target
参数不是 null
,则 target
的 run
方法在启动该线程时调用。如果 target 参数为 null
,则该线程的 run
方法在该线程启动时调用。
新创建线程的优先级被设定为创建该线程的线程的优先级,即当前正在运行的线程的优先级。方法 setPriority
可用于将优先级更改为一个新值。
当且仅当创建新线程的线程当前被标记为守护线程时,新创建的线程才被标记为守护线程。方法 setDaemon
可用于改变线程是否为守护线程。
group
- 线程组。
target
- 其
run
方法被调用的对象。
name
- 新线程的名称。
SecurityException
- 如果当前线程无法在指定的线程组中创建线程,或者无法重写上下文类加载器方法。
Runnable.run()
,
run()
,
setDaemon(boolean)
,
setPriority(int)
,
ThreadGroup.checkAccess()
,
SecurityManager.checkAccess(java.lang.Thread)
public Thread(ThreadGroup group, Runnable target, String name, long stackSize)
Thread
对象,以便将
target
作为其运行对象,将指定的
name
作为其名称,作为
group
所引用的线程组的一员,并具有指定的
堆栈大小。
除了允许指定线程堆栈大小以外,这种构造方法与 Thread(ThreadGroup,Runnable,String)
完全一样。堆栈大小是虚拟机要为该线程堆栈分配的地址空间的近似字节数。 stackSize 参数(如果有)的作用具有高度的平台依赖性。
在某些平台上,指定一个较高的 stackSize 参数值可能使线程在抛出 StackOverflowError
之前达到较大的递归深度。同样,指定一个较低的值将允许较多的线程并发地存在,且不会抛出 OutOfMemoryError
(或其他内部错误)。stackSize 参数的值与最大递归深度和并发程度之间的关系细节与平台有关。在某些平台上,stackSize 参数的值无论如何不会起任何作用。
作为建议,可以让虚拟机自由处理 stackSize 参数。如果指定值对于平台来说过低,则虚拟机可能使用某些特定于平台的最小值;如果指定值过高,则虚拟机可能使用某些特定于平台的最大值。 同样,虚拟机还会视情况自由地舍入指定值(或完全忽略它)。
将 stackSize 参数值指定为零将使这种构造方法与 Thread(ThreadGroup, Runnable, String) 构造方法具有完全相同的作用。
由于这种构造方法的行为具有平台依赖性,因此在使用它时要非常小心。执行特定计算所必需的线程堆栈大小可能会因 JRE 实现的不同而不同。鉴于这种不同,仔细调整堆栈大小参数可能是必需的,而且可能要在支持应用程序运行的 JRE 实现上反复调整。
实现注意事项:鼓励 Java 平台实现者文档化其 stackSize parameter 的实现行为。
group
- 线程组。
target
- 其
run
方法被调用的对象。
name
- 新线程的名称。
stackSize
- 新线程的预期堆栈大小,为零时表示忽略该参数。
SecurityException
- 如果当前线程无法在指定的线程组中创建线程。
方法详细信息 |
---|
public static Thread currentThread()
public static void yield()
public static void sleep(long millis) throws InterruptedException
millis
- 以毫秒为单位的休眠时间。
InterruptedException
- 如果任何线程中断了当前线程。当抛出该异常时,当前线程的
中断状态 被清除。
Object.notify()
public static void sleep(long millis, int nanos) throws InterruptedException
millis
- 以毫秒为单位的休眠时间。
nanos
- 要休眠的另外 0-999999 纳秒。
IllegalArgumentException
- 如果 millis 值为负或 nanos 值不在 0-999999 范围内。
InterruptedException
- 如果任何线程中断了当前线程。当抛出该异常时,当前线程的
中断状态 被清除。
Object.notify()
public void start()
run
方法。
结果是两个线程并发地运行;当前线程(从调用返回给 start
方法)和另一个线程(执行其 run
方法)。
多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。
IllegalThreadStateException
- 如果线程已经启动。
run()
,
stop()
public void run()
Runnable
运行对象构造的,则调用该
Runnable
对象的
run
方法;否则,该方法不执行任何操作并返回。
Thread
的子类应该重写该方法。
@Deprecated public final void stop()
ThreadDeath
异常的一个自然后果)。如果以前受这些监视器保护的任何对象都处于一种不一致的状态,则损坏的对象将对其他线程可见,这有可能导致任意的行为。stop
的许多使用都应由只修改某些变量以指示目标线程应该停止运行的代码来取代。目标线程应定期检查该变量,并且如果该变量指示它要停止运行,则从其运行方法依次返回。如果目标线程等待很长时间(例如基于一个条件变量),则应使用 interrupt
方法来中断该等待。有关更多信息,请参阅为何不赞成使用 Thread.stop、Thread.suspend 和 Thread.resume?。
如果安装了安全管理器,则以 this
作为其参数调用 checkAccess
方法。这可能引发 SecurityException
(在当前线程中)。
如果该线程不同于当前线程(即当前线程试图终止除它本身以外的某一线程),则安全管理器的 checkPermission
方法(带有 RuntimePermission("stopThread")
参数)也会被调用。这会再次抛出 SecurityException
(在当前线程中)。
无论该线程在做些什么,它所代表的线程都被迫异常停止,并抛出一个新创建的 ThreadDeath
对象,作为异常。
停止一个尚未启动的线程是允许的。 如果最后启动了该线程,它会立即终止。
应用程序通常不应试图捕获 ThreadDeath
,除非它必须执行某些异常的清除操作(注意,抛出 ThreadDeath
将导致 try
语句的 finally
子句在线程正式终止前执行)。如果 catch
子句捕获了一个 ThreadDeath
对象,则重新抛出该对象很重要,因为这样该线程才会真正终止。
对其他未捕获的异常作出反应的顶级错误处理程序不会打印输出消息,或者另外通知应用程序未捕获到的异常是否为 ThreadDeath
的一个实例。
@Deprecated public final void stop(Throwable obj)
stop()
。 该方法的附加危险是它可用于生成目标线程未准备处理的异常(包括若没有该方法该线程不太可能抛出的已检查的异常)。 有关更多信息,请参阅为何不赞成使用 Thread.stop、Thread.suspend 和 Thread.resume?。
如果安装了安全管理器,则调用该线程的 checkAccess
方法,这可能引发 SecurityException
(在当前线程中)。
如果该线程不同于当前线程(即当前线程试图终止除它本身以外的某一线程),或者 obj
不是 ThreadDeath
的一个实例,则安全管理器的 checkPermission
方法(带有 RuntimePermission("stopThread")
参数)也会被调用。 此外,这可能抛出 SecurityException
(在当前线程中)。
如果参数 obj
为 null,则抛出 NullPointerException
(在当前线程中)。
无论该线程在做些什么,它所代表的线程都被迫异常停止,并抛出 Throwable
对象 obj
,作为一个异常。这是一种不正常的操作,通常情况下,应使用不带任何参数的 stop
方法。
停止一个尚未启动的线程是允许的。 如果最后启动了该线程,它会立即终止。
obj
- 要抛出的可抛出对象。
SecurityException
- 如果当前线程不能修改该线程。
NullPointerException
- 如果 obj 为
null。
interrupt()
,
checkAccess()
,
run()
,
start()
,
stop()
,
SecurityManager.checkAccess(Thread)
,
SecurityManager.checkPermission(java.security.Permission)
public void interrupt()
如果当前线程没有中断它自己(这在任何情况下都是允许的),则该线程的 checkAccess
方法就会被调用,这可能抛出 SecurityException
。
如果线程在调用 Object
类的 wait()
、wait(long)
或 wait(long, int)
方法,或者该类的 join()
、j