java线程的生命周期及wait(),notify(),notifyAll()的详解分析

48 阅读3分钟

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个