多线程Thread,ThreadGroup和Runnable

Runnable接口以及Thread和ThreadGroup类支持多线程编程。下面分别予以说明。注意:关于管理线程,实现Runnable接口以及创建多线程程序的概述已在第11章中介绍过。 14.13.1 Runnable接口 Runnable接口必须由启动执行的独立线程的类所实现。Runnable仅定义了一种抽象方法,叫做run( )。该方法是线程的入口点。它的形式如下所示: abstract void run( ) 所创建的线程必须实现该方法。 14.13.2 Thread Thread创建一个新的执行线程。它定义了如下的构造函数: Thread( ) Thread(Runnable threadOb) Thread(Runnable threadOb, StringthreadName) Thread(String threadName) Thread(ThreadGroup groupOb, Runnable threadOb) Thread(ThreadGroup groupOb, Runnable threadOb, String threadName) Thread(ThreadGroup groupOb, String threadName) threadOb是实现Runnable接口的类的一个实例,它定义了线程运行开始的地方。线程的名字由threadName指定。当名字未被指定时,Java虚拟机将创建一个。groupOb指定了新线程所属的线程组。当没有线程组被指定时,新线程与其父线程属于同一线程组。下面的常数由Thread定义: MAX_PRIORITY MIN_PRIORITY NORM_PRIORITY 正如所期望的那样,这些常数指定了最大,最小以及默认的线程优先权。由Thread定义的方法列在表14-16中。在比Java 2早的版本中,Thread中也包括了stop( ),suspend( )以及resume( )方法。然而正如在第11章中解释的那样,这些方法由于其固有的不稳定性而在Java 2中被摈弃了。在Java 2中摈弃的还有countStackFrames( )方法,因为它调用了suspend( )方法。表14-16 由Thread定义的方法方法 描述 static int activeCount( ) 返回线程所属的线程组中线程的个数 void checkAccess( ) 引起安全管理程序检验当前的线程能访问和/或能改变在其上checkAccess( )方法被调用的线程 static Thread currentThread( ) 返回一个Thread对象,该对象封装了调用这个方法的线程 void destroy( ) 终止线程 static int enumerate(Thread threads[ ]) 将当前线程组中的所有Thread对象的拷贝放入threads中。返回线程的个数 ClassLoader getContextClassLoader( ) 返回用于对这个线程加载类和资源的类加载程序(在Java 2中新增加的) final String getName( ) 返回线程名 final int getPriority( ) 返回线程的属性设置 final ThreadGroup getThreadGroup( ) 返回调用线程是其中一个成员的ThreadGroup对象 void interrupt( ) 中断线程 static boolean interrupted( ) 如果当前执行的线程已经被预先设置了中断,则返回true;否则,返回false final boolean isAlive( ) 如果线程仍在运行中,则返回true;否则返回false final boolean isDaemon( ) 如果线程是一个后台进程线程(Java运行系统的一部分),则返回true;否则返回false boolean isInterrupted( ) 如果线程被中断,则返回true,否则返回false final void join( ) throws InterruptedException 等待直至线程终止 方法 描述 final void join(long milliseconds) throws InterruptedException 等待直到为终止线程而指定的以毫秒计时的时间 final void join(long milliseconds, int nanoseconds) throws InterruptedException 等待直到为终止线程而指定的以毫秒加毫微秒计时的时间 void run( ) 开始线程的执行 void setContextClassLoader(ClassLoader cl) 设置将被调用线程用于cl的类加载程序(在Java 2中新增加的) final void setDaemon(boolean state) 标记线程为后台进程线程 final void setName(String threadName) 将线程的名字设置为由threadName指定的名字 final void setPriority(int priority) 设置由priority指定的线程优先权 static void sleep(long milliseconds) throws InterruptedException 以指定的毫秒为单位的时间长度挂起执行的线程 static void sleep(long milliseconds, int nanoseconds) throws InterruptedException 以指定的毫秒加毫微秒为单位的时间长度挂起执行的线程 void start( ) 开始线程的执行 String toString( ) 返回线程的等价字符串形式 static void yield( ) 调用线程将CPU让给其他的线程 14.13.3 ThreadGroup 线程组(ThreadGroup)创建了一组线程。它定义了如下的两个构造函数: ThreadGroup(String groupName) ThreadGroup(ThreadGroup parentOb, String groupName) 对于两种形式,groupName指定了线程组的名字。第一种形式创建一个新的线程组,该线程组将当前的线程作为它的父线程。在第二种形式中,父线程由parentOb指定。由ThreadGroup定义的方法列在表14-17中。在比Java 2更早出现的Java版本中,ThreadGroup中也包括了stop( ),suspend( )以及resume( )方法。这些方法由于其本身固有的不稳定性,而在Java 2中被摈弃。表14-17 由ThreadGroup定义的方法方法 描述 int activeCount( ) 返回线程组加上以这个线程作为父类的所有线程组中线程的个数 int activeGroupCount( ) 返回调用线程是父类的线程的组数 final void checkAccess( ) 引起安全管理程序检验调用线程能访问和/或能改变在其上checkAccess( )方法被调用的线程组 续表方法 描述 final void destroy( ) 撤消被调用的线程组(以及任一子线程组) int enumerate(Thread group[ ]) 将构成调用线程组的线程放入group数组中 int enumerate(Thread group[ ], boolean all) 将构成调用线程组的线程放入group数组中。如果all为true,那么线程组的所有子线程组中的线程也被放入group中 int enumerate(ThreadGroup group[ ]) 将调用线程组的子线程组放入group数组中 int enumerate(ThreadGroup group[ ], boolean all) 将调用线程组的子线程组放入group数组中。如果all为true,所有子线程组的子线程组(等等)也被放入group中 final int getMaxPriority( ) 返回对线程组设置的最大优先权 final String getName( ) 返回线程组名 final ThreadGroup getParent( ) 如果调用ThreadGroup对象没有父类,则返回null;否则返回调用对象的父类 final void interrupt( ) 调用线程组中所有线程的interrupt( )方法(在Java 2中新增加的) final boolean isDaemon( ) 如果线程组是一个端口后台进程组,则返回true;否则返回false boolean isDestroyed( ) 如果线程组已经被破坏,则返回true;否则,返回false void list( ) 显示关于线程组的信息 final boolean parentOf(ThreadGroup group) 如果调用线程是group的父线程(或group本身),则返回true;否则返回false final void setDaemon(boolean isDaemon) 如果isDaemon为true,那么调用线程组被标记为一个端口后台进程组 final void setMaxPriority(int priority) 对调用线程组设置最大优先权priority String toString( ) 返回线程组的字符串等价形式 void uncaughtException(Thread thread, Throwable e) 当一个异常未被捕获时,该方法被调用 线程组提供了一种方便的方法,可以将一组线程当做一个单元来管理。这在想挂起或恢复一些相关的线程的情况下,是特别有用的。例如假想在一个程序中,有一组线程被用来打印文档,另一组线程被用来将该文档显示在屏幕上,同时另一组线程将文档保存为磁盘文件。如果打印被异常中止了,想用一种很简单的方法停止所有与打印有关的线程。线程组为这种处理提供了方便。下面的程序说明了这种用法,在程序中创建两个线程组,每一线程组中有两个线程: // Demonstrate thread groups. class NewThread extends Thread {


boolean suspendFlag;
</pre>


NewThread(String threadname, ThreadGroup tgOb) {
super(tgOb, threadname);
System.out.println("New thread: " + this);
suspendFlag = false;
start(); // Start the thread
}
</pre>


// This is the entry point for thread.
public void run() {
try {
for(int i = 5; i > 0; i--) {
System.out.println(getName() + ": " + i);
Thread.sleep(1000);
synchronized(this) {
while(suspendFlag) {
wait();
}
}
}
} catch (Exception e) {
System.out.println("Exception in " + getName());
}
System.out.println(getName() + " exiting.");
}
</pre>


void mysuspend() {
suspendFlag = true;
}
</pre>


synchronized void myresume() {
suspendFlag = false;
notify();
}
</pre>


}


class ThreadGroupDemo {


public static void main(String args[]) {
ThreadGroup groupA = new ThreadGroup("Group A");
ThreadGroup groupB = new ThreadGroup("Group B");
</pre>


NewThread ob1 = new NewThread("One", groupA);
NewThread ob2 = new NewThread("Two", groupA);
NewThread ob3 = new NewThread("Three", groupB);
NewThread ob4 = new NewThread("Four", groupB);
</pre>


System.out.println("\nHere is output from list():");
groupA.list();
groupB.list();
System.out.println();
</pre>


System.out.println("Suspending Group A");
Thread tga[] = new Thread[groupA.activeCount()];
groupA.enumerate(tga); // get threads in group
for(int i = 0; i < tga.length; i++) {
((NewThread)tga[i]).mysuspend(); // suspend each thread
}
</pre>


try {
Thread.sleep(4000);
} catch (InterruptedException e) {
System.out.println("Main thread interrupted.");
}
</pre>


System.out.println("Resuming Group A");
for(int i = 0; i < tga.length; i++) {
((NewThread)tga[i]).myresume(); // resume threads in group
}
</pre>


// wait for threads to finish
try {
System.out.println("Waiting for threads to finish.");
ob1.join();
ob2.join();
ob3.join();
ob4.join();
} catch (Exception e) {
System.out.println("Exception in Main thread");
}
System.out.println("Main thread exiting.");
}
</pre>


} 该程序的一个输出样本如下所示: New thread: Thread[One,5,Group A] New thread: Thread[Two,5,Group A] New thread: Thread[Three,5,Group B] New thread: Thread[Four,5,Group B] Here is output from list(): java.lang.ThreadGroup[name=Group A,maxpri=10]


Thread[One,5,Group A]
Thread[Two,5,Group A]
</pre>


java.lang.ThreadGroup[name=Group B,maxpri=10]


Thread[Three,5,Group B]
Thread[Four,5,Group B]
</pre>


Suspending Group A Three: 5 Four: 5 Three: 4 Four: 4 Three: 3 Four: 3 Three: 2 Four: 2 Resuming Group A Waiting for threads to finish. One: 5 Two: 5 Three: 1 Four: 1 One: 4 Two: 4 Three exiting. Four exiting. One: 3 Two: 3 One: 2 Two: 2 One: 1 Two: 1 One exiting. Two exiting. Main thread exiting. 注意在这个程序中,线程组A被挂起四秒。由于输出确认,造成线程One和线程Two暂停,但是线程Three和线程Four仍然运行。四秒钟之后,线程One和线程Two被恢复。注意线程组A是如何被挂起和恢复的。首先通过对线程组A调用enumerate( )方法得到线程组A中的线程。然后每一个线程重复通过得到的数组而被挂起。为了恢复线程组A中的线程,序列再一次被遍历,每一个线程被恢复。最后一点:这个例子使用了Java 2推荐使用的方法去完成挂起和恢复线程的任务。而没有用在Java 2中被摈弃的方法suspend( )和resume( )。

取自“http://codex.wordpress.org.cn/Thread%EF%BC%8CThreadGroup%E5%92%8CRunnable”
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值