1.在同步方法中使用wait()、notify()方法 首先要理解notify()和wait(),按照Think in Java中的解释:"wait()允许我们将线程置入"睡眠"状态,同时又"积极"地等待条件发生改变.而且只有在一个notify()或 notifyAll()发生变化的时候,线程才会被唤醒,并检查条件是否有变." "wait()允许我们将线程置入"睡眠"状态",也就是说,wait也是让当前线程阻塞的,这一点和sleep或者suspend是相同的. 那和sleep,suspend有什么区别呢? 区别在于"(wait)同时又"积极"地等待条件发生改变",这一点很关键,sleep和suspend无法做到.因为我们需要通过同步(synchronized)的帮助来防止线程之间的冲突,而一旦使用同步,就要锁定对象,也就是获取对象锁,其它要使用该对象锁的线程都只能排队等着, 等到同步方法或者同步块里的程序全部运行完才有机会.在同步方法和同步块中,无论sleep()还是suspend()都不可能自己被调用的时候解除锁定,他们都霸占着正在使用的对象锁不放.而wait却可以,它可以让同步方法或者同步块暂时放弃对象锁。在同步方法中使用wait()方法,使本线程等待,并允许其他线程使用这个同步方法。 其他线程使用完这个同步方法后,等待的线程怎么把对象锁收回来呢? 第一种方法,限定借出去的时间.在wait()中设置参数,比如wait(1000),以毫秒为单位,就表明我只借出去1秒中,一秒钟之后,我自动收回. 第二种方法,让在使用的线程通知我,他用完了,要还给我了.调用notify()方法进行通知。 2.具体例子 生产者和消费者是从OS中的许多实际同步问题中抽象出来的具有代表性的问题。通过一个生产者--消费者的例子来说明synchronized和wait,notify之间的关系。 生产者生产,消费者消费。由于生产者和消费者彼此独立,且运行速度不确定。所以很可能出现生产者已进行生产,而消费者还没有得到信息的情况。为此,需要引入一组存储单元,组成缓冲区域,以便存放生产者所生产的信息。 如果要使生产者和消费者进程协调,必须定义如下规则: 1)只要缓存有存储单元,生产者可以进行生产,但当缓存已满,生产者必须等待 2)只要缓存不为空,消费者可以进行消费;但当缓存为空,消费者必须等待。 3)生产者和消费者不能同时读写缓存。 源码如下: (1)消费者
- public class Consumer implements Runnable {
- private Mointor m;
- public Consumer(Mointor m) {
- this.f = f;
- new Thread(this, "Consumer").start();
- }
-
- public void run() {
- while(true) {
- if(!f.suspend)
- {
- f.put();
- }
- }
- }
- }
复制代码 (2)生产者类- public class Producer implements Runnable{
- private Mointor m;
- public Producer(Mointor m) {
- this.m = m;
- new Thread(this, "Producer").start();
- }
- public void run() {
- int i = 0;
- while(true) {
- if(!f.suspend)
- {
- f.put(i++);
- }
- }
- }
- }
复制代码 (3)管理类- public class Mointor{
- int product_count = 0;
- int product_item;
- int front=0,rear=0;
- final static int MAX_NUM = 10;
- int[] buffer = new int[MAX_NUM];
- public synchronized int get() {
- if(product_count == 0)
- try {
- System.out.println("没有库存了,消费者等待……");
- Thread.sleep(1000);
- wait();
- } catch(InterruptedException e) {
- System.out.println("捕获中断异常");
- }
- product_item=buffer[front];
- product_count--;
- front=(front + 1)%MAX_NUM;
- System.out.println("消费者获得了一个产品。 仓库剩余产品数量为:" + (product_count));
- notify();
- return product_item;
- }
-
- public synchronized void put(int value) {
- if(product_count == MAX_NUM)
- try {
- System.out.println("仓库已满,生产者等待……");
- Thread.sleep(1000);
- wait();
- } catch(InterruptedException e) {
- System.out.println("捕获中断异常");
- }
- buffer[rear]=value;
- rear=(rear + 1)%MAX_NUM;
- product_count++
- System.out.println("生产者制造了一个产品。 仓库剩余产品数量为:" + product_count);
- notify();
- }
-
- public static void main(String[] args){
- Mointor m = new Mointor();
- Producer p = new Producer(m);
- p.safeResume();
- Consumer c = new Consumer(m);
- }
- }
复制代码
|