黑马程序员技术交流社区

标题: 线程问题,只输出一次,就报异常,看看哪里出了错 [打印本页]

作者: android-liu    时间: 2015-3-13 16:07
标题: 线程问题,只输出一次,就报异常,看看哪里出了错
  1. package com.xiangying.thread;

  2. import javax.xml.transform.OutputKeys;

  3. public class ThreadSave {

  4.         /**
  5.          * @param args
  6.          */
  7.         public static void main(String[] args) {
  8.                 Thread t = new Thread(new Input());
  9.                 Thread t1 = new Thread(new Output());

  10.                 t.start();
  11.                 t1.start();

  12.         }

  13. }

  14. // 饿汉式单例设计模式设计学生类:只能有一个对象
  15. class Student {

  16.         private String name;
  17.         private String sex;
  18.         boolean flag = false;
  19.         private static Student stu = new Student();

  20.         private Student() {
  21.         };

  22.         public static Student getStudent() {
  23.                 return stu;

  24.         }

  25.         public String getName() {
  26.                 return name;
  27.         }

  28.         public void setName(String name) {
  29.                 this.name = name;
  30.         }

  31.         public String getSex() {
  32.                 return sex;
  33.         }

  34.         public void setSex(String sex) {
  35.                 this.sex = sex;
  36.         }

  37.         public static Student getStu() {
  38.                 return stu;
  39.         }

  40.         public static void setStu(Student stu) {
  41.                 Student.stu = stu;
  42.         }

  43. }

  44. // 设计存入数据线程
  45. class Input implements Runnable {
  46.         Student s = Student.getStudent();
  47.         int x = 0;

  48.         @Override
  49.         public void run() {
  50.                 while (true) {
  51.                         synchronized (s) {
  52.                                 if (s.flag)
  53.                                         try {
  54.                                                 s.wait();
  55.                                         } catch (InterruptedException e1) {
  56.                                                 // TODO Auto-generated catch block
  57.                                                 e1.printStackTrace();
  58.                                         }
  59.                                 if (x == 0) {
  60.                                         s.setName("张三");
  61.                                         try {
  62.                                                 Thread.sleep(10);
  63.                                         } catch (InterruptedException e) {
  64.                                                 // TODO Auto-generated catch block
  65.                                                 e.printStackTrace();
  66.                                         }
  67.                                         s.setSex("男");
  68.                                 } else {

  69.                                         s.setName("lili");
  70.                                         try {
  71.                                                 Thread.sleep(10);
  72.                                         } catch (InterruptedException e) {
  73.                                                 // TODO Auto-generated catch block
  74.                                                 e.printStackTrace();
  75.                                         }
  76.                                         s.setSex("nvnvnnvnvnvnnv");
  77.                                 }
  78.                         }
  79.                         x = (x + 1) % 2;
  80.                         s.flag = true;
  81.                         s.notify();
  82.                 }
  83.         }
  84. }

  85. // 设计输出线程
  86. class Output implements Runnable {
  87.         Student s = Student.getStudent();

  88.         @Override
  89.         public void run() {
  90.                 while (true)
  91.                         synchronized (s) {
  92.                                 if (!s.flag)
  93.                                         try {
  94.                                                 s.wait();
  95.                                         } catch (InterruptedException e) {
  96.                                                 // TODO Auto-generated catch block
  97.                                                 e.printStackTrace();
  98.                                         }
  99.                                 System.out.println(s.getName() + "-----" + s.getSex());
  100.                                 s.flag = false;
  101.                                 notify();
  102.                         }

  103.         }

  104. }
复制代码

作者: sh1tge    时间: 2015-3-13 22:08
说几个明显的错误;
第一是你获取学生对象的时机不对
第二Input 类中 部分代码应该写进同步代码中 而你没有
第三output类中 notify 应该为 s.notify
第四while 循环少了个{

总之lz写代码的条理性有点乱...

顺便附上修改过后的
  1. public class ThreadSave {

  2.         /**
  3.          * @param args
  4.          */
  5.         public static void main(String[] args) {
  6.                         Student s = Student.getStudent();
  7.                 Thread t = new Thread(new Input(s));
  8.                 Thread t1 = new Thread(new Output(s));

  9.                 t.start();
  10.                 t1.start();

  11.         }

  12. }

  13. // 饿汉式单例设计模式设计学生类:只能有一个对象
  14. class Student {

  15.         private String name;
  16.         private String sex;
  17.         boolean flag = false;
  18.         private  static final Student stu = new Student();

  19.         private Student() {
  20.         }

  21.         public static Student getStudent() {
  22.                 return stu;

  23.         }

  24.         public String getName() {
  25.                 return name;
  26.         }

  27.         public void setName(String name) {
  28.                 this.name = name;
  29.         }

  30.         public String getSex() {
  31.                 return sex;
  32.         }

  33.         public void setSex(String sex) {
  34.                 this.sex = sex;
  35.         }

  36.      

  37. }

  38. // 设计存入数据线程
  39. class Input implements Runnable {
  40.         private Student s;
  41.                 Input( Student s){
  42.                 this.s = s;
  43.                 }
  44.         int x = 0;

  45.         @Override
  46.         public void run() {
  47.                 while (true) {
  48.                         synchronized (s) {
  49.                                 if (s.flag)
  50.                                         try {
  51.                                                 s.wait();
  52.                                         } catch (InterruptedException e1) {
  53.                                                 // TODO Auto-generated catch block
  54.                                                 e1.printStackTrace();
  55.                                         }
  56.                                 if (x == 0) {
  57.                                         s.setName("张三");
  58.                                         try {
  59.                                                 Thread.sleep(10);
  60.                                         } catch (InterruptedException e) {
  61.                                                 // TODO Auto-generated catch block
  62.                                                 e.printStackTrace();
  63.                                         }
  64.                                         s.setSex("男");
  65.                                 } else {

  66.                                         s.setName("lili");
  67.                                         try {
  68.                                                 Thread.sleep(10);
  69.                                         } catch (InterruptedException e) {
  70.                                                 // TODO Auto-generated catch block
  71.                                                 e.printStackTrace();
  72.                                         }
  73.                                         s.setSex("nvnvnnvnvnvnnv");
  74.                                 }
  75.                                                  x = (x + 1) % 2;
  76.                         s.flag = true;
  77.                         s.notify();
  78.                         }
  79.                        
  80.                 }
  81.         }
  82. }

  83. // 设计输出线程
  84. class Output implements Runnable {
  85.        private Student s;
  86.                 Output( Student s){
  87.                 this.s = s;
  88.                 }
  89.         @Override
  90.         public void run() {
  91.                 while (true){
  92.                         synchronized (s) {
  93.                                 if (!s.flag)
  94.                                         try {
  95.                                                 s.wait();
  96.                                         } catch (InterruptedException e) {
  97.                                                 // TODO Auto-generated catch block
  98.                                                 e.printStackTrace();
  99.                                         }
  100.                                 System.out.println(s.getName() + "-----" + s.getSex());
  101.                                 s.flag = false;
  102.                                 s.notify();
  103.                         }

  104.         }

  105. }
  106. }
复制代码

作者: 大神在何方    时间: 2015-3-13 23:39
看到那么多代码,以后我要是也会就好了。好怕自己学不会啊·感觉自己脑子不好使。会了成就感可大了
作者: Jaybor    时间: 2015-3-14 08:56
如果你有多个输入输出线程还应该把if(flag)修改成while(flag),把notify修改成notifyAll()




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2