1.java线程的生命周期    线程是一个动态执行的过程,它也有一个从产生到死亡的过程。

(1)生命周期的五种状态

    新建(new Thread)    当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。
    例如:Thread  t1=new Thread();

    就绪(runnable)    线程已经被启动,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等候得到CPU资源。例如:t1.start();

    运行(running)    线程获得CPU资源正在执行任务(run()方法),此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束。

    死亡(dead)

自然终止:正常运行run()方法后终止

异常终止:调用方法stop()让一个线程终止运行

    堵塞(blocked)
    由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态。

正在睡眠:用sleep(long t) 方法可使线程进入睡眠方式。一个睡眠着的线程在指定的时间过去可进入就绪状态。

正在等待:调用wait()方法。(调用motify()方法回到就绪状态)

被另一个线程所阻塞:调用suspend()方法。(调用resume()方法恢复)

2.常用方法

setPriority( ) 设置线程的优先权;

void run()   创建该类的子类时必须实现的方法

void start() 开启线程的方法

static void sleep(long t) 释放CPU的执行权,不释放锁

final void wait() 释放CPU的执行权,释放锁。类似sleep( ), 不同的是,wait( )会先释放锁住的对象,然后再执行等待的动作。注意,这个函数属于                                  Object类。另外,由于wait( )所等待的对象必须先锁住,因此,它只能用在同步化程序段或者同步化方法内,否则,会抛出异                                         常IllegalMonitorStateException.

final void notify() 唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程(随机)。直到当前的线程                                     放弃此对象上的锁,才能继续执行被唤醒的线程。同Wait方法一样,notify只能由持有对像锁的线程来调用.notifyall也一样,不                                       同的是notifyall会唤配所有在此对象锁上等待的线程。"只能由持有对像锁的线程来调用"说明wait方法与notify方法必须在同步块

                            内执行,即synchronized(obj)之内.再者synchronized代码块内没有锁是寸步不行的,所以线程要继续执行必须获得锁,相辅相成.

join( ): 等待加入的线程执行完毕才会执行下一个线程。加入的线程通过interrupt( )来唤醒。

static void yied()暂停线程的执行,给其它具有相同优先权的线程执行的机会,若此时没有其它线程执行,则此线程继续执行。这个函数并不会释                                   放锁住的对象。

      wait导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或被其他线程中断。wait只能由持有对像锁的线程来调用。


       注意:

wait(),notify(),notifyAll()不属于Thread类,而是属于Object基础类,也就是说每个对象都有wait(),notify(),notifyAll()的功能.因为每个对象都有锁,锁是每个对象的基础,当然操作锁的方法也是最基础了。

3.wait(),notify(),notifyAll()的详解分析

很经典的例子(生产者与消费者):
首先是消费者线程类:

import java.util.List;  
public class Consume implements Runnable {  
 private List container = null;  
 private int count;  
 public Consume(List lst) {  
  this.container = lst;  
 }  
 public void run() {  
  while (true) {  
   synchronized (container) {  
    if (container.size() == 0) {  
     try {  
      container.wait();// 容器为空,放弃锁,等待生产  
     } catch (InterruptedException e) {  
      e.printStackTrace();  
     }  
    }  
    try {  
     Thread.sleep(1000);  
    } catch (InterruptedException e) {  
     e.printStackTrace();  
    }  
    container.remove(0);  
    container.notify();  
    System.out.println("我吃了" + (++count) + "个");  
   }  
  }  
 }  
}




接下来是生产者线程类:




import java.util.List;
public class Product implements Runnable {
 private List container = null;
 private int count;
 public Product(List lst) {
  this.container = lst;
 }
 public void run() {
  while (true) {
   synchronized (container) {
    if (container.size() > MultiThread.MAX) {
     // 如果容器超过了最大值,就不要在生产了,等待消费
     try {
      container.wait();
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
    }
    try {
     Thread.sleep(1000);
    } catch (InterruptedException e) {
     e.printStackTrace();
    }
    container.add(new Object());
    container.notify();
    System.out.println("我生产了" + (++count) + "个");
   }
  }
 }
}




最后是测试类:

import java.util.ArrayList;
import java.util.List;
public class MultiThread {
 private List container = new ArrayList();
 public final static int MAX = 10;
 public static void main(String args[]) {
  MultiThread m = new MultiThread();
  new Thread(new Consume(m.getContainer())).start();
  new Thread(new Product(m.getContainer())).start();
 }
 public List getContainer() {
  return container;
 }
 public void setContainer(List container) {
  this.container = container;
 }
}



运行结果如下所示:

我生产了1个
我吃了1个
我生产了2个
我生产了3个
我生产了4个
我生产了5个
我生产了6个
我生产了7个
我吃了2个
我生产了8个
我吃了3个
我生产了9个
我吃了4个
我吃了5个
我吃了6个
我吃了7个
我吃了8个
我生产了10个
我生产了11个
我吃了9个
我生产了12个
我吃了10个

......