WEB开发网
开发学院软件开发Java Java中线程的高级应用 阅读

Java中线程的高级应用

 2010-10-05 01:23:09 来源:WEB开发网   
核心提示:(6)suspend() / resume() 方法和wait() / notify() 方法的对比l suspend()/resume() 方法两个方法配套使用,suspend()使得线程进入阻塞状态,Java中线程的高级应用(6),并且不会自动恢复,必须其对应的resume() 被调用,守护线程一般被用于在后台为

(6)suspend() / resume() 方法和wait() / notify() 方法的对比
l  suspend()/resume() 方法
两个方法配套使用,suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的resume() 被调用,才能使得线程重新进入可执行状态。典型地,suspend() 和 resume() 被用在等待另一个线程产生的结果的情形:测试发现结果还没有产生后,让线程阻塞,另一个线程产生了结果后,调用 resume() 使其恢复。
l  wait()/notify() 方法
两个方法配套使用,wait() 使得线程进入阻塞状态,它有两种形式,一种允许 指定以毫秒为单位的一段时间作为参数,另一种没有参数,前者当对应的 notify() 被调用或者超出指定时间时线程重新进入可执行状态,后者则必须对应的 notify() 被调用。
l  两者的对比
区别的核心在于,suspend()/resume() 方法,阻塞时都不会释放占用的锁(如果占用了的话),而wait()/notify() 方法则相反。
首先,suspend()/resume() 方法都隶属于 Thread 类,而wait()/notify() 方法却直接隶属于 Object 类,也就是说,所有对象都拥有这一对方法。
其次,suspend()/resume() 方法都可在任何位置调用,但是wait()/notify() 方法却必须在 synchronized 方法或块中调用,理由也很简单,只有在synchronized 方法或块中当前线程才占有锁,才有锁可以释放。若不满足这一条件,则程序虽然仍能编译,但在运行时会出现IllegalMonitorStateException 异常。
关于 wait()/notify() 方法的两点说明:
第一:调用 notify() 方法导致解除阻塞的线程是从因调用该对象的 wait() 方法而阻塞的线程中随机选取的,我们无法预料哪一个线程将会被选择,所以编程时要特别小心,避免因这种不确定性而产生问题。
第二:除了 notify(),还有一个方法 notifyAll() 也可起到类似作用,唯一的区别在于,调用 notifyAll() 方法将把因调用该对象的 wait() 方法而阻塞的所有线程一次性全部解除阻塞。当然,只有获得锁的那一个线程才能进入可执行状态。
 
4、线程优先级

(1)优先级(共10级):
它们决定线程执行的先后次序(优先级高者先执行)并可以通过Thread类中的setPriority()和getPriority()方法来改变和获取优先级。

(2)典型的优先级码Thread.MIN_PRIORITY (1级)、Thread.MAX_PRIORITY(10级)、Thread.NORM_PRIORITY(5级)

(3)调度规则:
优先级高者的线程先执行,然后再执行优先级低者;但对相同优先级的线程的执行次序将取决于目标操作系统的设计方式(时间片设计方式,即抢先式----轮循执行;非时间片设计方式,即非抢先式---先创建者先执行,然后再另一个。此时容易产生"自私"线程)。

class ThreadTest
{
 public static void main(String args[])
 {
  Thread ThreadOne=new MyThread("Thread One");
  ThreadOne.setPriority(Thread.MIN_PRIORITY);
  ThreadOne.start();
  Thread ThreadTwo=new MyThread("Thread Two");
  ThreadTwo.setPriority(Thread.MAX_PRIORITY);
  ThreadTwo.start();
  Thread ThreadThree=new MyThread("Thread Three");
  ThreadThree.setPriority(Thread.MAX_PRIORITY);
  ThreadThree.start();
 }
}

class MyThread extends Thread
{
 String threadName;
 MyThread(String nameString)
 {
  threadName=nameString ;
 }
 public void run()
 {
  for(int I=0; I<3; I++)
  {
   System.out.println(threadName+" "+getPriority() );
  }
 }
}

5、线程组
利用它可以将多个线程集合为一个单独的对象,到达对这些线程共同操作(如统一启动一组线程或挂起一组线程等),创建出线程组并加入指定的线程成员(也可以是子线程组,形成树状层次结构)。
线程是被个别创建的,但可以将它们归类到线程组中,以便于调试和监视。只能在创建线程的同时将它与一个线程组相关联。在使用大量线程的程序中,使用线程组组织线程可能很有帮助。可以将它们看作是计算机上的目录和文件结构。
线程组是一个 Java 特有的概念,在 Java 中,线程组是类ThreadGroup 的对象,每个线程都隶属于唯一一个线程组,这个线程组在线程创建时指定并在线程的整个生命期内都不能更改。可以通过调用包含 ThreadGroup 类型参数的 Thread 类构造函数来指定线程属的线程组,若没有指定,则线程缺省地隶属于名为 system 的系统线程组。
在 Java 中,除了预建的系统线程组外,所有线程组都必须显式创建。在 Java 中,除系统线程组外的每个线程组又隶属于另一个线程组,你可以在创建线程组时指定其所隶属的线程组,若没有指定,则缺省地隶属于系统线程组。这样,所有线程组组成了一棵以系统线程组为根的树。
Java 允许我们对一个线程组中的所有线程同时进行操作,比如我们可以通过调用线程组的相应方法来设置其中所有线程的优先级,也可以启动或阻塞其中的所有线程。
Java 的线程组机制的另一个重要作用是线程安全。线程组机制允许我们通过分组来区分有不同安全特性的线程,对不同组的线程进行不同的处理,还可以通过线程组的分层结构来支持不对等安全措施的采用。Java 的 ThreadGroup 类提供了大量的方法来方便我们对线程组树中的每一个线程组以及线程组中的每一个线程进行操作。
 
 

ThreadGroup aThreadGroup=new ThreadGroup("线程组名");
Thread aThread=new Thread(aThreadGroup,"线程名");
aThread.getThreadGroup();  //返回线程组对象aThreadGroup

(1)ThreadGroup类成员函数
(2)影响组内各个线程的组函数:resume()、stop()、suspend()。
 
6、守护线程
守护线程是一类特殊的线程,它和普通线程的区别在于它并不是应用程序的核心部分,当一个应用程序的所有非守护线程终止运行时,即使仍然有守护线程在运行,应用程序也将终止,反之,只要有一个非守护线程在运行,应用程序就不会终止。守护线程一般被用于在后台为其它线程提供服务。
可以通过调用方法 isDaemon() 来判断一个线程是否是守护线程,也可以调用方法 setDaemon() 来将一个线程设为守护线程。

上一页  1 2 3 4 5 6 

Tags:线程

编辑录入:coldstar [复制链接] [打 印]
赞助商链接