`
战斗为了生存
  • 浏览: 20904 次
  • 性别: Icon_minigender_1
  • 来自: 青岛
文章分类
社区版块
存档分类
最新评论

多线程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”
分享到:
评论

相关推荐

    【Java多线程】Thread和Runnable创建新线程区别

    这是一道面试题,创建多线程时,使用继承Thread类和实现Runnable接口有哪些区别呢? 一、Thread 先来看看Thread类和其中的start()方法 class Thread implements Runnable{.....} // 可见,Thread类实现了Runnable...

    线程 JAVA java线程 java线程第3版 java线程第2版第3版合集

    本书第二版提供了对Thread和ThreadGroup类、Runnable接口和语言的同步操作符内容的全面讨论。它解释了如何在不同的平台上调度线程,如何开发CPUScheduler类来实现你自己的调度策略。其他扩展例子包括实现读/写锁、...

    Java线程/内存模型的缺陷和增强

    它提供了Thread/Runnable/ThreadGroup等一系列封装的类和接口,让程序员可以高效的开发Java多线程应用。为了实现同步,Java提供了synchronize关键字以及object的wait()/notify()机制,可是在简单易用的背后,应藏着...

    汪文君高并发编程实战视频资源全集

    │ 高并发编程第二阶段33讲、多线程Thread-Per-Message设计模式.mp4 │ 高并发编程第二阶段34讲、多线程Two Phase Termination设计模式-上.mp4 │ 高并发编程第二阶段35讲、多线程Two Phase Termination设计模式-...

    汪文君高并发编程实战视频资源下载.txt

    │ 高并发编程第二阶段33讲、多线程Thread-Per-Message设计模式.mp4 │ 高并发编程第二阶段34讲、多线程Two Phase Termination设计模式-上.mp4 │ 高并发编程第二阶段35讲、多线程Two Phase Termination设计模式-...

    超级有影响力霸气的Java面试题大全文档

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    java 面试题 总结

    与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...

    java面试题

    答:多线程有两种实现方法,一种是继承Thread类或者实现Runnable接口。同步就是在方法返回类型后面加上synchronized。 c#中的委托,事件是不是委托? 答:委托就是将方法作为一个参数带入另一个方法叫做委托,事件...

    Java开发技术大全(500个源代码).

    ThreadImRunnable.java 继承Runnable接口实现多线程 mulThread.java 创建多个线程对象的类 demoJoin.java 演示使用join()以确保主线程最后结束 clicker.java 一个计数用的线程类 demoPri.java 调用上面这个类...

    java经典面试2010集锦100题(不看你后悔)

    B) 在Java中布尔类型不能和数字之间不能来回转换,即false和true不对应任何零或非零的值。 C) 双精度类型double比单精度类型float具有更高的精度和更大的表示范围,但float类型具有速度快、占用内存小的优点。 D) 在...

Global site tag (gtag.js) - Google Analytics