package java.lang;
import java.io.PrintStream;
import sun.misc.VM;
/**
*
* 用于处理一组线程的类
* 它是一种树状结构,他的下层节点还可以是ThreadGroup对象
*
* comment by liqiang
*
*/
public
class ThreadGroup {
//父级的线程组对象
ThreadGroup parent;
//线程组的名字
String name;
//线程组的最大优先级数,线程组所含线程不得超过此值
int maxPriority;
boolean destroyed;
boolean daemon;
boolean vmAllowSuspension;
int nthreads;
Thread threads[];
int ngroups;
ThreadGroup groups[];
/**
*
* 创建一个空的线程组,它不属于任何线程组,相当于根线程组
* 他的名为system,此方法由c调用
*
*/
private ThreadGroup() {
//设置线程组的名字为system
this.name = "system";
//设置线程组的最大优先级,为线程规定的最大优先级
this.maxPriority = Thread.MAX_PRIORITY;
}
/**
*
* 构造函数
*
*/
public ThreadGroup(String name) {
//使用当前线程的线程组
this(Thread.currentThread().getThreadGroup(), name);
}
/**
*
* 构造函数
* @param parent 父线程组
* @param name 线程组的名字
*
*/
public ThreadGroup(ThreadGroup parent, String name) {
if (parent == null) {
throw new NullPointerException();
}
//安全检查
parent.checkAccess();
//通过父线程组初始化当前新建的线程组
this.name = name;
this.maxPriority = parent.maxPriority;
this.daemon = parent.daemon;
this.vmAllowSuspension = parent.vmAllowSuspension;
this.parent = parent;
//将新建线程组加入到父线程组
parent.add(this);
}
/**
*
* 返回线程组名
*
*/
public final String getName() {
return name;
}
/**
*
* 获得父线程组
*
*/
public final ThreadGroup getParent() {
if (parent != null)
parent.checkAccess();
return parent;
}
/**
*
* 获得线程组的最大优先级值
*
*/
public final int getMaxPriority() {
return maxPriority;
}
/**
*
* 判断当前线程组是否是Daemon
* 如果此线程组是Daemon的,如果他的只有一个线程且线程终止
* 或它只有一个线程组,且这个线程组销毁,则当前线程组销毁
*
* @return true表示当前线程组是Daemon,false表示不是
*/
public final boolean isDaemon() {
return daemon;
}
/**
*
* 判断当前线程组是否被销毁
*
*/
public synchronized boolean isDestroyed() {
return destroyed;
}
/**
*
* 设置线程组的Daemon状态
* @param daemon true表示设置为Daemon线程组,false表示设置为非Daemon线程组
*
*/
public final void setDaemon(boolean daemon) {
checkAccess();
this.daemon = daemon;
}
/**
*
* 设置线程组的最大优先级
* @param pri 新的优先级值,比当前对象的线程组最大值小才会被设置,否则被忽略
*
*/
public final void setMaxPriority(int pri) {
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
synchronized (this) {
checkAccess();
if (pri < Thread.MIN_PRIORITY) {
//如果比最小优先级小则使用最小优先级
maxPriority = Thread.MIN_PRIORITY;
} else if (pri < maxPriority) {
//如果设置的优先级比当前线程组的最大值小则
//将它置为当前对象的最大优先级,如果比当前的最大
//优先级大或想的则还使用原来的最大优先级
maxPriority = pri;
}
ngroupsSnapshot = ngroups;
if (groups != null) {//如果此对象有线程组对象
//创建新的线程组数组
groupsSnapshot = new ThreadGroup[ngroupsSnapshot];
//将当前对象中的线程组对象拷贝到新创建的数组中
//做拷贝是为了保证线程安全
System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot);
} else {
//如果当前对象不包含线程组对象,则将groupsSnapshot置为null
groupsSnapshot = null;
}
}
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
//递归设置所有的子线程组的最大优先级
groupsSnapshot[i].setMaxPriority(pri);
}
}
/**
*
* 盘段当前线程组对象是否是指定线程组对象
* 的父线程组
*
*/
public final boolean parentOf(ThreadGroup g) {
//查询线程组数,判断当前对象是否是给定对象的父线程组
for (; g != null ; g = g.parent) {
if (g == this) {
//是之地对象的父线程组返回true
return true;
}
}
//不是返回false
return false;
}
/**
*
* 安全检查
*
*/
public final void checkAccess() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkAccess(this);
}
}
/**
*
* 取得此线程组中的所有活动线程数(包括子线程组)
*
*/
public int activeCount() {
int result;
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
synchronized (this) {
if (destroyed) {//如果线程组已被销毁则直接返回0
return 0;
}
//取得包含的线程数,他是计算所含线程数的基数
result = nthreads;
//取得包含的线程组数
ngroupsSnapshot = ngroups;
if (groups != null) {
//如果包括的子线程组数组不为空,则生成新的线程组数组
//并将当前对象的子线程组拷贝到新建数组中
groupsSnapshot = new ThreadGroup[ngroupsSnapshot];
System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot);
} else {
//将临时变量置为null
groupsSnapshot = null;
}
}
//算出所包含所有线程数,线程组包含的线程数与所有子线程组的线程数和
//子线程组的线程数是递归算出的
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
result += groupsSnapshot[i].activeCount();
}
return result;
}
/**
*
* 递归(处理子线程组)的将当前线程组中的所有Alive线程对象
* 拷贝到List中
*
*/
public int enumerate(Thread list[]) {
checkAccess();
return enumerate(list, 0, true);
}
/**
*
* 将当前线程组中的所有Alive线程对象拷贝到List中
*
* @param list 拷贝的目标数组
* @param recurse 表示是否处理子线程组中的线程对象
*/
public int enumerate(Thread list[], boolean recurse) {
checkAccess();
return enumerate(list, 0, recurse);
}
//将当前线程组中的Alive线程个数拷贝到list中,
//n为开始填充的位置,recurse表示是否递归处理
//表示是否递归读取子线程组Alive的线程对象
private int enumerate(Thread list[], int n, boolean recurse) {
int ngroupsSnapshot = 0;
ThreadGroup[] groupsSnapshot = null;
synchronized (this) {
if (destroyed) {//如果线程组被销毁则返回0
return 0;
}
int nt = nthreads;
if (nt > list.length - n) {
//如果空余个数比所含线程数大,则使用空余个数
nt = list.length - n;
}
//将Alive的线程对象放到数组的相应位置
for (int i = 0; i < nt; i++) {
if (threads[i].isAlive()) {
list[n++] = threads[i];
}
}
if (recurse) {//如果需要处理子线程数组的线程对象
ngroupsSnapshot = ngroups;
//如果当前线程组数组不为null
//生成新的线程组数组,并将当前线程组对象拷贝到新建线程组数组
if (groups != null) {
groupsSnapshot = new ThreadGroup[ngroupsSnapshot];
System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot);
} else {
groupsSnapshot = null;
}
}
}
if (recurse) {
//如果处理子线程数组,则递归的将子线程数组的Alive的
//线程对象拷贝到数组中
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
n = groupsSnapshot[i].enumerate(list, n, true);
}
}
//返回获取的线程个数
return n;
}
/**
*
* 判断当前线程组中线程组的个数
* 是递归计算的(计算子线程组中的个数,依次向下)
*
*/
public int activeGroupCount() {
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
synchronized (this) {
if (destroyed) {
return 0;
}
ngroupsSnapshot = ngroups;
//如果当前线程组数组不为null
//生成新的线程组数组,并将当前线程组对象拷贝到新建线程组数组
if (groups != null) {
groupsSnapshot = new ThreadGroup[ngroupsSnapshot];
System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot);
} else {
groupsSnapshot = null;
}
}
int n = ngroupsSnapshot;
//递归计算
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
n += groupsSnapshot[i].activeGroupCount();
}
return n;
}
/**
*
* 递归的将当前线程组中包含的线程组拷贝到list中
*
*/
public int enumerate(ThreadGroup list[]) {
checkAccess();
return enumerate(list, 0, true);
}
/**
*
* 将当前线程组中包含的线程组拷贝到list中
* @param list 拷贝的目标数组
* @param recurse true表示递归处理,fale不递归处理
* 递归处理指递归拷贝每个子线程组中的子线程组
*/
public int enumerate(ThreadGroup list[], boolean recurse) {
checkAccess();
return enumerate(list, 0, recurse);
}
//将当前线程组中包含的线程组拷贝到list中
//表示其实位置,recurse为true表示递归处理,fale不递归处理
//递归处理指递归拷贝每个子线程组中的子线程组
private int enumerate(ThreadGroup list[], int n, boolean recurse) {
int ngroupsSnapshot = 0;
ThreadGroup[] groupsSnapshot = null;
synchronized (this) {
if (destroyed) {
//如果此线程组已被销毁则直接返回0
return 0;
}
int ng = ngroups;
if (ng > list.length - n) {
//计算将要填充的个数,输入数组的剩余长度
//比所含的线程数组个数小,则只填充剩余长度个数的线程数组元素
ng = list.length - n;
}
//将所含的线程组拷贝到list中
if (ng > 0) {
System.arraycopy(groups, 0, list, n, ng);
n += ng;
}
if (recurse) {//如果计算子线程组
ngroupsSnapshot = ngroups;
if (groups != null) {
//生成新的线程组,并将原线程组元素拷贝到新线程组中
groupsSnapshot = new ThreadGroup[ngroupsSnapshot];
System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot);
} else {
groupsSnapshot = null;
}
}
}
if (recurse) {
//递归拷贝每个子线程组中的子线程组
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
n = groupsSnapshot[i].enumerate(list, n, true);
}
}
//返回当前线程组包含的总的线程组个数
return n;
}
/**
*
* 停止线程组树中的所有线程,不建议被使用
* @deprecated
*/
public final void stop() {
//停止线程组树中的所有线程(如果有此当前线程,不做处理)
//如果线程组树中包括当前对象则停止当前对象
if (stopOrSuspend(false))
Thread.currentThread().stop();
}
/**
*
* 递归中断线程组树中的所有线程
*
*/
public final void interrupt() {
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
synchronized (this) {
checkAccess();
//中断当前线程组下的线程
for (int i = 0 ; i < nthreads ; i++) {
threads[i].interrupt();
}
ngroupsSnapshot = ngroups;
//如果当前线程组包含子线程组
//生成新的线程组,并将原线程组元素拷贝到新线程组中
if (groups != null) {
groupsSnapshot = new ThreadGroup[ngroupsSnapshot];
System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot);
} else {
groupsSnapshot = null;
}
}
//递归中断每个子线程组下的线程,和其线程组中的线程
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
groupsSnapshot[i].interrupt();
}
}
/**
*
* 挂起线程组树中的所有线程,不建议被使用
* @deprecated
*
*/
public final void suspend() {
//挂起线程组树中的所有线程
//如果线程组树中包括当前对象则挂起当前对象
if (stopOrSuspend(true))
Thread.currentThread().suspend();
}
/**
*
* 挂起或中断当前线程组树中的所有线程,如果包括当前线程,
* 则不做处理,但是返回自杀标记
* suspend为true表示为挂起操作,为false表示为停止操作
*
**/
private boolean stopOrSuspend(boolean suspend) {
boolean suicide = false;
//获取当前线程
Thread us = Thread.currentThread();
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot = null;
synchronized (this) {
checkAccess();
for (int i = 0 ; i < nthreads ; i++) {
if (threads[i]==us)//如果此线程对象是自己,则标志自杀位为true
suicide = true;
else if (suspend)//suspend为true,做挂起处理
threads[i].suspend();
else//suspend为false做停止处理
threads[i].stop();
}
ngroupsSnapshot = ngroups;
//如果当前线程组包含子线程组
//生成新的线程组对象,并将当前线程组对象拷贝到数组中
if (groups != null) {
groupsSnapshot = new ThreadGroup[ngroupsSnapshot];
System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot);
}
}
//递归处理子线程组,有一个线程组为自杀状态则标志为自杀状态
for (int i = 0 ; i < ngroupsSnapshot ; i++)
suicide = groupsSnapshot[i].stopOrSuspend(suspend) || suicide;
return suicide;
}
/**
*
* 唤醒线程组树中的所有线程,不建议被使用
* @deprecated
*
*/
public final void resume() {
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
synchronized (this) {
checkAccess();
for (int i = 0 ; i < nthreads ; i++) {
threads[i].resume();
}
ngroupsSnapshot = ngroups;
//如果当前线程组包含子线程组
//生成新的线程组对象,并将当前线程组对象拷贝到数组中
if (groups != null) {
groupsSnapshot = new ThreadGroup[ngroupsSnapshot];
System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot);
} else {
groupsSnapshot = null;
}
}
//递归唤醒每个子线程组下的线程,和其线程组中的线程
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
groupsSnapshot[i].resume();
}
}
/**
*
* 销毁线程组中的每个子线程组
*
*/
public final void destroy() {
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
synchronized (this) {
checkAccess();
if (destroyed || (nthreads > 0)) {
//如果已经被销毁,或当前线程组没有活动线程则抛出异常
throw new IllegalThreadStateException();
}
ngroupsSnapshot = ngroups;
if (groups != null) {
//如果当前线程组包含子线程组
//生成新的线程组对象,并将当前线程组对象拷贝到数组中
groupsSnapshot = new ThreadGroup[ngroupsSnapshot];
System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot);
} else {
//将表示子线程组的数组置空
groupsSnapshot = null;
}
if (parent != null) {
//表示不是System线程组,做清楚操作
destroyed = true;
ngroups = 0;
groups = null;
nthreads = 0;
threads = null;
}
}
//递归销毁每个子线程组下的线程组
//注意ngroupsSnapshot为0是递归的终止条件
for (int i = 0 ; i < ngroupsSnapshot ; i += 1) {
groupsSnapshot[i].destroy();
}
//从父线程组中删除
if (parent != null) {
parent.remove(this);
}
}
/**
*
* 向此线程组对象中添加一个子线程组
*
*/
private final void add(ThreadGroup g){
synchronized (this) {
if (destroyed) {//如果当前线程组已经销毁则抛出异常
throw new IllegalThreadStateException();
}
if (groups == null) {
//如果线程组中没有子线程组,则生成新的线程组数组
groups = new ThreadGroup[4];
} else if (ngroups == groups.length) {//如果已满
//生成原来2倍大长度的线程组数组,并将原线程组元素拷贝到新数组中
ThreadGroup newgroups[] = new ThreadGroup[ngroups * 2];
System.arraycopy(groups, 0, newgroups, 0, ngroups);
//新数组置为当前线程组数组变量
groups = newgroups;
}
//将此线程组加入到子线程组数组中
//注意ngroups表示个数,在数组中表示下一个插入的位置
groups[ngroups] = g;
//子线程组个数加1
ngroups++;
}
}
/**
*
* 从当前线程组中删除指定子线程组
*
*/
private void remove(ThreadGroup g) {
synchronized (this) {
if (destroyed) {//如果当前线程组已经销毁则直接返回
return;
}
for (int i = 0 ; i < ngroups ; i++) {//轮循子线程组
if (groups[i] == g) {
//如果找到此线程组元素,则长度减1,数组从此位置后一位向前移动
//使得在数组中清除此元素
ngroups -= 1;
System.arraycopy(groups, i + 1, groups, i, ngroups - i);
//将最后一个元素置为null
groups[ngroups] = null;
//清除成功跳出循环
break;
}
}
if (nthreads == 0) {
notifyAll();
}
if (daemon && (nthreads == 0) && (ngroups == 0)) {
//如果当前线程是daemo,且没有线程和线程组,则销毁此线程组
destroy();
}
}
}
/**
*
* 向线程组中添加线程
*
*/
void add(Thread t) {
synchronized (this) {
if (destroyed) {//如果线程组已经销毁则抛出异常
throw new IllegalThreadStateException();
}
if (threads == null) {
//如果当前线程组没有此线程,则创建存放线程的数组
threads = new Thread[4];
} else if (nthreads == threads.length) {
//如果存线程的数组已满,则创建一个新的线程数组
//长度为原来的2倍,并将原来的线程对象拷贝到新建数组中
Thread newthreads[] = new Thread[nthreads * 2];
System.arraycopy(threads, 0, newthreads, 0, nthreads);
threads = newthreads;
}
//将要添加的线程对象添加到数组中
threads[nthreads] = t;
//线程个数加1
nthreads++;
}
}
/**
*
* 删除当前线程组中的指定线程(不做递归)
*
*/
void remove(Thread t) {
synchronized (this) {
if (destroyed) {//如果线程组已经销毁则直接返回
return;
}
for (int i = 0 ; i < nthreads ; i++) {
if (threads[i] == t) {
//如果找到此线程元素,则长度减1,数组从此位置后一位向前移动
//使得在数组中清除此元素
System.arraycopy(threads, i + 1, threads, i, --nthreads - i);
threads[nthreads] = null;
//清除成功跳出循环
break;
}
}
if (nthreads == 0) {
notifyAll();
}
//如果当前线程是daemo,且没有线程和线程组,则销毁此线程
if (daemon && (nthreads == 0) && (ngroups == 0)) {
destroy();
}
}
}
/**
*
* 在标准输出(System.out)中打印出线程组中的信息
* 此方法用于调试
*
*/
public void list() {
list(System.out, 0);
}
/**
*
* 向流中打印线程组中的信息
*
* @param out PrintStream的流
* @param indent 缩进数
*
*/
void list(PrintStream out, int indent) {
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
synchronized (this) {
//打印出indent个空格用来表示缩进
for (int j = 0 ; j < indent ; j++) {
out.print(" ");
}
//toString方式
out.println(this);
//做4个缩进
indent += 4;
for (int i = 0 ; i < nthreads ; i++) {
for (int j = 0 ; j < indent ; j++) {
out.print(" ");
}
//打印出线程组中的每个线程的信息
out.println(threads[i]);
}
ngroupsSnapshot = ngroups;
if (groups != null) {
//生成一个新的数组,并将原来的线程对象拷贝到此线程组中
groupsSnapshot = new ThreadGroup[ngroupsSnapshot];
System.arraycopy(groups, 0, groupsSnapshot, 0, ngroupsSnapshot);
} else {
//如果没有子线程组,groupsSnapshot初始化为null
groupsSnapshot = null;
}
}
//将子线程组中的信息(递归得到)打印到流中
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
groupsSnapshot[i].list(out, indent);
}
}
/**
* 当线程组由于未处理异常停止时,此方法被虚拟机调用
* 如果此线程组有父线程组则调用父线程组的此方法
* 如果没有父线程组,判断如果此线程不是ThreadDeath则打印出异常
*
*/
public void uncaughtException(Thread t, Throwable e) {
if (parent != null) {//如果有父线程组,则递归调有父线程组的此方法
parent.uncaughtException(t, e);
} else if (!(e instanceof ThreadDeath)) {
//如果线程不是ThreadDeath则打印出异常
e.printStackTrace(System.err);
}
}
/**
* @deprecated
*/
public boolean allowThreadSuspension(boolean b) {
this.vmAllowSuspension = b;
if (!b) {
VM.unsuspendSomeThreads();
}
return true;
}
/**
*
* 线程组的字符串表示形式
* 一个示例java.lang.ThreadGroup[name=main,maxpri=10]
*/
public String toString() {
return getClass().getName() + "[name=" + getName() + ",maxpri=" + maxPriority + "]";
}
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/liqj2ee/archive/2006/01/16/581220.aspx
分享到:
相关推荐
`ThreadGroup`用于管理一组线程,而`ThreadLocal`提供线程局部变量,确保每个线程都有自己的独立副本。`ClassLoader`负责加载类,`SecurityManager`则提供了安全管理机制。 `Runnable`接口定义了`run()`方法,任何...
java.lang包还包含了一些与安全、线程和内存管理相关的类,如SecurityManager用于安全管理,Thread和ThreadGroup是线程相关的类,ClassLoader负责加载类,ThreadLocal为每个线程提供独立的变量副本,而Runtime类提供...
- ThreadGroup:表示一个线程组,用于组织管理相关的线程。 - ThreadLocal:用于提供线程内部的局部变量。 6. 实用工具类: - String:表示字符串,提供了丰富的字符串操作方法。 - StringBuffer:表示字符序列...
线程组是Java中对线程进行组织和管理的一种方式,它是`java.lang.ThreadGroup`类的实例。线程组可以包含线程和其他线程组,允许我们对一组线程进行分组操作,比如监控、统计或安全管理。 在描述中提到,“没有用...
- B、`java.lang.ThreadGroup`: 线程组的实现。 - C、`java.lang.Thread`: 线程的实现。 - D、`java.lang.Runnable`: 可运行接口。 - **答案**: B - **解析**: `ThreadGroup`类提供了线程组的功能,用于管理一组...
最后,`Thread`和`ThreadGroup`类构成了Java的多线程机制,`ThreadLocal`则提供线程私有的变量,确保每个线程都有自己的副本,不会互相干扰。 总的来说,`java.lang`包是Java程序的基础,其提供的类和接口构成了...
- 学习Java的线程模型,如JVM如何调度线程,可以阅读JDK源码中`java.lang.Thread`和`java.lang.ThreadGroup`的相关实现。 - 分析`synchronized`和`volatile`的底层实现,了解内存模型(Java Memory Model)对并发...
比如,使用`ThreadGroup.interrupt()`中断群组内的所有线程,或者通过`ThreadGroup.stop()`强制停止(尽管不推荐,因为这种方式可能导致资源泄露和其他问题)。 此外,实例可能还会涉及Java并发库中的其他组件,如`...
5. **多线程**:`java.lang.Thread`类和`java.util.concurrent`包提供了线程管理和并发控制,如`Runnable`接口、`ThreadGroup`、`Semaphore`、`ExecutorService`等。 6. **异常处理**:`java.lang.Throwable`及其...
5. **多线程**:`java.lang.Thread` 类和相关接口定义了多线程编程的基本概念,如 `Runnable` 和 `ThreadGroup`。Java 1.6 对线程同步和通信进行了优化,引入了更高级的并发工具,如 `java.util.concurrent` 包下的 ...
ThreadGroup parentThread; for (parentThread = Thread.currentThread().getThreadGroup(); parentThread.getParent() != null; parentThread = parentThread.getParent()); int totalThread = parentThread....
Thread(ThreadGroup group, Runnable target, String name, long stackSize) ``` #### 三、Java线程:线程栈模型与线程的变量 - **线程栈模型** 每个线程都有自己的栈空间,用于存储方法调用的信息,如局部...
- `Thread(ThreadGroup group, Runnable target, String name, long stackSize)` **3. 启动线程** 启动线程是通过调用`Thread`对象的`start()`方法完成的。调用`start()`方法会创建一个新的执行线程,并使该线程...
最后,`java.lang.ThreadGroup`类是线程的容器,可以用来组织和管理线程。它可以用于设置线程的优先级、检查线程状态,甚至杀死线程。 总结起来,Java线程源码的学习涵盖了线程的创建、管理、同步和通信等多个方面...
17. **Thread/ThreadGroup/ThreadLocal/InheritableThreadLocal**:线程相关的类,提供了多线程编程的支持。 18. **Throwable/Error/AssertionError/LinkageError/ClassCircularityError/ClassFormatError/...
5. 线程组和线程优先级:ThreadGroup和线程优先级也是管理线程时的重要概念。线程组提供了组织和控制一组线程的方式,线程优先级则允许我们对线程调度的优先顺序进行设置。 6. Java虚拟机(JVM)对线程的支持:JVM...
线程组通过`ThreadGroup`类实现,可以嵌套创建,形成树状结构。线程在创建时可以指定其所属的线程组。 总结来说,Java多线程提供了强大的工具和机制来处理并发问题,包括线程的创建、调度、同步和互斥,以及线程组...
Java中的线程模型由三部分构成:虚拟CPU(封装在`java.lang.Thread`类中)、执行的代码(传递给`Thread`类)和处理的数据(传递给`Thread`类)。创建线程有两种主要方式: 1. **继承`Thread`类**:自定义一个类继承...