A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 郑彬 于 2012-8-17 23:19 编辑

r.wait();冻结
r.notify();叫醒(默认叫醒系统中前面冻结的那一个线程)
r.notifyAll();叫醒所有的线程
以上3种方法。都使用在同步中,因为要对持有监视器(锁)的线程操作。
所以要使用在同步中,因为只有同步才具有锁。
解释看不懂,能解释一下为什么吗?

4 个回复

正序浏览
问题已经解决
回复 使用道具 举报
一个比较经典的问题:生产者/消费者问题,这个问题的解决就是通过灵活使用wait()、notifyALL()方法实现的。
问题描述:
生产者将产品交给店员,而消费者从店员处取走产品,店员一次只能持有固定数量的产品,如果生产者生产了过多的产品,店员就会叫生产者等一下,如果店中有空位放产品了再通知消费者来取走产品。这里可能出现的问题有一下两个:
1、生产者比消费者快时,消费者会漏掉一些数据没有取到
2、消费者比生产者快时,消费者会取相同的数据
一下代码就是解决方案:
//生产者消费者问题
public class ProductTest {

        public static void main(String[] args) {
                Clerk clerk = new Clerk();
                // 生产者线程
                Thread producerThread = new Thread(new Producer(clerk));
                // 消费者线程
                Thread consumerThread = new Thread(new Consumer(clerk));

                producerThread.start();
                consumerThread.start();
        }
}

// 店员
class Clerk {
        // 默认为0个产品
        private int product = 0;

        // 生产者生产出来的产品交给店员
        public synchronized void addProduct() {
                if (this.product >= 20) {
                        try {
                                // 产品已满,请稍候再生产
                                wait();
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                } else {
                        product++;
                        System.out.println("生产者生产第" + product + "个产品");
                        // 通知等待区的消费者可以取产品了
                        notifyAll();
                }
        }

        // 消费者从店员处取产品
        public synchronized void getProduct() {
                if (this.product <= 0) {
                        try {
                                // 缺货,请稍候再取
                                wait();
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                } else {
                        System.out.println("消费者取走了第" + product + "个产品");
                        product--;
                        // 通知等待区的生产者可以生产产品了
                        notifyAll();
                }
        }
}

class Producer implements Runnable {
        private Clerk clerk;

        public Producer(Clerk clerk) {
                this.clerk = clerk;
        }

        public void run() {
                System.out.println("生产者开始生产产品");
                while (true) {
                        try {
                                Thread.sleep((int) (Math.random() * 10) * 100);
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                        // 生产产品
                        clerk.addProduct();
                }
        }
}

class Consumer implements Runnable {
        private Clerk clerk;

        public Consumer(Clerk clerk) {
                this.clerk = clerk;
        }

        public void run() {
                System.out.println("消费者开始取走产品");
                while (true) {
                        try {
                                Thread.sleep((int) (Math.random() * 10) * 100);
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                        // 取产品
                        clerk.getProduct();
                }
        }
}

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1 很给力!

查看全部评分

回复 使用道具 举报
下图也许会方便你的理解:
回复 使用道具 举报
举例:抓人游戏。
             定位,定住:其实就是wait
             被人拍醒:其实就是notify
           所有被抓的人都定住了,然后,说重玩:其实就是notifyAll
如果你玩过就应该明白
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马