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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 郭军亮 中级黑马   /  2013-5-15 17:39  /  1603 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 郭军亮 于 2013-5-15 21:30 编辑
  1. package xuexi1;

  2. public class InputOutputDemo2 {

  3.         /**
  4.          * @param args
  5.          */
  6.         public static void main(String[] args) {
  7.                 // TODO Auto-generated method stub
  8.                 Resource1 r1=new Resource1();
  9.                 new Thread(new Input1(r1)).start();
  10.                 new Thread(new Output1(r1)).start();
  11.         }

  12. }
  13. class Resource1{
  14.         private String name;
  15.         private String sex;
  16.         boolean flag=false;
  17.         public synchronized void set(String name,String sex){
  18.                 if(flag){
  19.                         try{        
  20.                                 this.wait();
  21.                            }
  22.                         catch(Exception e){
  23.                                 System.out.println(e.toString());
  24.                            }
  25.                    }
  26.                
  27.            else {
  28.                 this.name=name;
  29.                 this.sex=sex;
  30.                 flag=true;
  31.                 this.notify();
  32.            }
  33.         }
  34.         public synchronized void get(){
  35.                 if(!flag){
  36.                         try{
  37.                                 this.wait();
  38.                         }
  39.                         catch(Exception e){
  40.                                 e.printStackTrace();
  41.                         }
  42.                 }
  43.                 else{
  44.                      System.out.println(this.name+"....."+this.sex);
  45.                      flag=false;
  46.                      this.notify();
  47.                 }
  48.         }
  49. }
  50. class Input1 implements Runnable{
  51.         Resource1 res;
  52.         
  53.         Input1(Resource1 res){
  54.                 this.res=res;
  55.         }
  56.         @Override
  57.         public void run(){
  58.                 int i=0;
  59.                 while(true){
  60.                         if(i==0)
  61.                                 res.set("123","456");
  62.                         else if(i==1){
  63.                                 res.set("ggggg","asdf");
  64.                         }
  65.                         i=(i+1)%2;
  66.                 }
  67.         }
  68. }
  69. class Output1 implements Runnable{
  70.         Resource1 res;
  71.         Output1(Resource1 res){
  72.                 this.res=res;
  73.         }
  74.            public void run() {
  75.                    while(true){
  76.                            res.get();
  77.                    }
  78.             }
  79.         
  80. }
复制代码
执行结果为
123.....456
123.....456
123.....456
123.....456
123.....456
123.....456
123.....456
但是不是应该为123.....456和ggggg.....asdf交替出现吗?

评分

参与人数 1技术分 +2 收起 理由
滔哥 + 2

查看全部评分

8 个回复

正序浏览
xuemeng 发表于 2013-5-15 18:42
public class Demo {
public static void main(String[] args) {
  Resource1 r1 = new Resource1();

没有复制啊, 他的代码有问题, 我是用他的代码来给他说明,代码的运行步骤, 然后又给出正确的代码啊!!:L
回复 使用道具 举报
十分感谢,找好长时间错误了,终于知道了,谢谢
回复 使用道具 举报
郭军亮 发表于 2013-5-15 20:55
为什么结果不是123.....456和ggggg.....asdf交替出现的呢?

我的回答不是很清楚了吗?
回复 使用道具 举报
高新星 发表于 2013-5-15 18:36
可能是你执行的时间短吧!
我运行的结果:

为什么结果不是123.....456和ggggg.....asdf交替出现的呢?
回复 使用道具 举报
本帖最后由 xuemeng 于 2013-5-15 21:08 编辑

public class Demo {
public static void main(String[] args) {
  Resource1 r1 = new Resource1();
  new Thread(new Input1(r1)).start();
  new Thread(new Output1(r1)).start();
}
}
class Resource1 {
private String name;
private String sex;
boolean flag = false;
public synchronized void set(String name, String sex) {
//6, 这是flag的值是true了, 那么线程等待了
  if (flag) {
   try {
//10, Input线程本来是等到这里的, 现在被唤醒了, 本来线程应该继续往下执行的, 如果真往下执行的话, 那么name, sex 的值别是   gggg, asdf, 可是, 因为你这里是一个if...else语句, 那么这就意味着, 你执行if 语句了, else 语句就不会执行,  那么程序又回到第4步, 回到第4 步后 ,执行完第4步后, i的值又变为0了, 那么这时程序执行第2步, 那么这时的值依然是 123, 456, 打印就不会交叉了
    this.wait();
   } catch (Exception e) {
    System.out.println(e.toString());
   }
//3, 程序走到这里来了,执行这里代码, 因为flag为false, 所以执行else语句, name , sex 分别被赋值123, 456, 方法执行完成,程序继续执行, flag = true
  } else {// 这里的else 不能要
   this.name = name;
   this.sex = sex;
   flag = true;
   this.notify();
  }
}
public synchronized void get() {
//9, 线程等待,接下来第10步就是关键地方了, 程序出错就在这里
  if (!flag) {
   try {
    this.wait();
   } catch (Exception e) {
    e.printStackTrace();
   }
  } else {
//8, 打印    name = 123,  sex = 456;
   System.out.println(this.name + "....." + this.sex);
   flag = false;
   this.notify();
  }
}
}
class Input1 implements Runnable {
Resource1 res;
Input1(Resource1 res) {
  this.res = res;
}
//1, 假设程序new Thread(new Input1(r1)).start() 这个线程先开启,
public void run() {
  int i = 0;
  while (true) {
   if (i == 0)
//2, 程序走到这里, 调用  set方法, 执行该方法
    res.set("123", "456");
   else if (i == 1) {
//5, 继续循环执行到这里, 再调用set方法
    res.set("ggggg", "asdf");
   }
//4, 当 res.set("123", "456")方法结束, 执行这里, i == 1, 然后程序,继续while循环,
   i = (i + 1) % 2;
  }
}
}
class Output1 implements Runnable {
Resource1 res;
Output1(Resource1 res) {
  this.res = res;
}
public void run() {
  while (true) {
//7, 线程被唤醒执行.
   res.get();
  }
}
}

下面的代码是正确代码::
public class Demo {
public static void main(String[] args) {
  Resource1 r1 = new Resource1();
  new Thread(new Input1(r1)).start();
  new Thread(new Output1(r1)).start();
}
}
class Input1 implements Runnable {
Resource1 res;
Input1(Resource1 res) {
  this.res = res;
}
public void run() {
  int i = 0;
  while (true) {
   if (i == 0) {
    res.set("123", "456");
   } else if (i == 1) {
    res.set("ggggg", "asdf");
   }
   i = (i + 1) % 2;
  }
}
}
class Output1 implements Runnable {
Resource1 res;
Output1(Resource1 res) {
  this.res = res;
}
public void run() {
  while (true) {
   res.get();
  }
}
}
class Resource1 {
private String name;
private String sex;
boolean flag = false;
public synchronized void set(String name, String sex) {
  if (flag) {
   try {
    this.wait();
   } catch (Exception e) {
    System.out.println(e.toString());
   }
  }
  this.name = name;
  this.sex = sex;
  flag = true;
  this.notify();
}
public synchronized void get() {
  if (!flag) {
   try {
    this.wait();
   } catch (Exception e) {
    e.printStackTrace();
   }
  } else {
   System.out.println(this.name + "....." + this.sex);
   flag = false;
   this.notify();
  }
}
}


评分

参与人数 1技术分 +1 收起 理由
滔哥 + 1 勉强给分吧,下次别复制。

查看全部评分

回复 使用道具 举报
可能是你执行的时间短吧!
我运行的结果:

捕获.PNG (85.82 KB, 下载次数: 0)

捕获.PNG

评分

参与人数 1技术分 +1 收起 理由
滔哥 + 1

查看全部评分

回复 使用道具 举报
我这个就是两个线程公用一个资源类,让两个线程交替运行的,但结果却不是交替运行的啊?请帮忙看看?
回复 使用道具 举报
你是创建了两个线程没错,但是:
Resource1 r1=new Resource1(); 你只是创建了一个资源类。

还要创建一个Output1的资源类 ,分出来一个线程来运行启动。

这就是使用实现接口中一个注意的地方。你看一下相关的视频。

这是我的理解,如果有错的地方指点一下,谢谢了!!!

评分

参与人数 1技术分 +1 收起 理由
滔哥 + 1

查看全部评分

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