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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 赵庆礼 中级黑马   /  2012-6-24 23:49  /  1489 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由  赵庆礼 于 2012-6-25 10:56 编辑

class Res {
        private String name;
        private String sex;
        private boolean flag = false;
        public synchronized void Set(String name, String sex) {
                if (flag)
                {
                        try {
                                this.wait();
                        } catch (Exception e) {
                        }
                 }
                  this.name = name;
                  this.sex = sex;
                  flag = true;
                  this.notify();
        }
        public synchronized void Out() {
                if (flag)
                        try {
                                this.wait();
                        } catch (Exception e) {
                        }
                System.out.println(name + "......." + sex);
                flag = false;
                this.notify();
        }
}
class Input implements Runnable {
        private Res r;
        Input(Res r) {
                this.r = r;
        }
        public void run() {
                int x = 0;
                while (true) {
                        if (x == 0)
                                r.Set("mike", "man");
                        else
                                r.Set("小红", "女");
                        x = (x + 1) % 2;
                }
        }
}
class Output implements Runnable {
        private Res r;
        Output(Res r) {
                this.r = r;
        }
        public void run() {
                while (true) {
                        r.Out();
                }
        }
}
public class ThreadWaitDemo {
        public static void main(String args[]) {
                Res r = new Res();
                new Thread(new Input(r)).start();
                new Thread(new Output(r)).start();
        }
}


这是我看完毕老师的视频,按照毕老师的思路写的,但是不对,大侠帮忙看看哪儿出错了。

1 个回复

倒序浏览
本帖最后由 周兴中 于 2012-6-25 00:28 编辑

public synchronized void Set(String name, String sex) {
                if (flag) //用if来判断有个缺点,当之前等待的线程被再次唤醒时,不再判断标记,而继续往下执行,会造成多输入一次数据.
                {
                        try {
                                this.wait();
                        } catch (Exception e) {
                        }
                 }
                  this.name = name;
                  this.sex = sex;
                  flag = true;
                  this.notify();  //notify()是按先进先出的原则唤醒线程池中等待的线程,如果判断标记处用while语句,将有可能出现所有线程都处于等待状态,导致程序出现类似冻结的状态.所以
                                        当判断标记用while时,此处用notifyALL().

        }
        public synchronized void Out() {
                if (flag) // 此处标记应该是判断false 既if(!flag)
                        try {
                                this.wait();
                        } catch (Exception e) {
                        }
                System.out.println(name + "......." + sex);
                flag = false;
                this.notify();
        }

你这个程序当只有一个输入线程和一个输出线程时可以正常运行,但是当出现多个输入线程和输出线程时,会出现输入多次,却只输出一次;或输入一次,却输出多次的情况.

建议使用 while()判断标记,notifyAll()唤醒所有等待线程的方式.

例:
while(flag)
                        try {
                                this.wait();
                        } catch (Exception e) {
                        }
                System.out.println(name + "......." + sex);
                flag = false;
                this.notifyAll();

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马