Java线程基本概念与方法


线程的生命周期

  新建状态:用new语句创建的线程对象处于新建状态,此时它和其它的java对象一样,仅仅在堆中被分配了内存 
  就绪状态:当一个线程创建了以后,其他的线程调用了它的start()方法,该线程就进入了就绪状态。处于这个状态的线程位于可运行池中,等待获得CPU的使用权 
  运行状态:处于这个状态的线程占用CPU,执行程序的代码 
  阻塞状态:当线程处于阻塞状态时,java虚拟机不会给线程分配CPU,直到线程重新进入就绪状态,它才有机会转到运行状态。 
    

  阻塞状态分为三种情况: 
  1、 位于对象等待池中的阻塞状态:当线程运行时,如果执行了某个对象的wait()方法,java虚拟机就回把线程放到这个对象的等待池中 
  2、 位于对象锁中的阻塞状态,当线程处于运行状态时,试图获得某个对象的同步锁时,如果该对象的同步锁已经被其他的线程占用,JVM就会把这个线程放到这个对象的琐池中。 
  3、 其它的阻塞状态:当前线程执行了sleep()方法,或者调用了其它线程的join()方法,或者发出了I/O请求时,就会进入这个状态中。

 

一、创建并运行线程

  在Java中创建线程有两种方法:继承Thread类和实现Runnable接口。
  要注意的是Thread类也实现了Runnable接口,因此,从Thread类继承的类的实例也可以作为target传入这个构造方法。可通过这种方法实现多个线程的资源共享。
  当调用start方法后,线程开始执行run方法中的代码。线程进入运行状态。可以通过Thread类的isAlive方法来判断线程是否处于运行状态。当线程处于运行状态时,isAlive返回true,当isAlive返回false时,可能线程处于等待状态,也可能处于停止状态。

二、挂起和唤醒线程

  一但线程开始执行run方法,就会一直到这个run方法执行完成这个线程才退出。但在线程执行的过程中,可以通过两个方法使线程暂时停止执行。这两个方法是suspend和sleep。在使用suspend挂起线程后,可以通过resume方法唤醒线程。而使用sleep使线程休眠后,只能在设定的时间后使线程处于就绪状态(在线程休眠结束后,线程不一定会马上执行,只是进入了就绪状态,等待着系统进行调度)。

  虽然suspend和resume可以很方便地使线程挂起和唤醒,但由于使用这两个方法可能会造成一些不可预料的事情发生,因此,这两个方法被标识为deprecated(抗议)标记,这表明在以后的jdk版本中这两个方法可能被删除,所以尽量不要使用这两个方法来操作线程。

三、终止线程的三种方法

  有三种方法可以使终止线程。
  1.  使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
  2.  使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。
  3.  使用interrupt方法中断线程。

 

Object类的方法:

  wait() :表示等待获取某个对象锁,执行了该方法的线程释放对象的锁,JVM会把该线程放到对象的等待池中。该线程等待其它线程唤醒(notify、notifyAll)。

  notify(): 执行该方法的线程唤醒在对象的等待池中等待的一个线程,JVM从对象的等待池中随机选择一个线程,把它转到对象的锁池中。使线程由阻塞队列进入就绪状态

Thread类的方法:

  join():调用该方法的主线程等待此线程死亡后再继续,可使异步线程变为同步线程

  interrupt():中断线程,被中断线程会抛InterruptedException  

  sleep():让当前正在执行的线程休眠,有一个用法可以代替yield函数——sleep(0)。该方法不会释放锁标志的。

  yield():暂停当前正在执行的线程对象,并执行其他线程。也就是交出CPU一段时间。该方法不会释放锁标志的。  

  sleep和yield区别:  

  1、sleep()方法会给其他线程运行的机会,而不考虑其他线程的优先级,因此会给较低线程一个运行的机会;yield()方法只会给相同优先级或者更高优先级的线程一个运行的机会。如果较高优先级的线程没有调用 sleep 方法,又没有受到 I/O阻塞,那么较低优先级线程只能等待所有较高优先级的线程运行结束,才有机会运行。

  2、当线程执行了sleep(long millis)方法后,将转到阻塞状态,参数millis指定睡眠时间;当线程执行了yield()方法后,将转到就绪状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。
  3、sleep()方法声明抛出InterruptedException异常,而yield()方法没有声明抛出任何异常
  4、sleep()方法比yield()方法具有更好的移植性

 

posted @ 2014-04-07 15:57  红胡子的老人  阅读(197)  评论(0编辑  收藏  举报