黑马程序员技术交流社区
标题:
线程问题,只输出一次,就报异常,看看哪里出了错
[打印本页]
作者:
android-liu
时间:
2015-3-13 16:07
标题:
线程问题,只输出一次,就报异常,看看哪里出了错
package com.xiangying.thread;
import javax.xml.transform.OutputKeys;
public class ThreadSave {
/**
* @param args
*/
public static void main(String[] args) {
Thread t = new Thread(new Input());
Thread t1 = new Thread(new Output());
t.start();
t1.start();
}
}
// 饿汉式单例设计模式设计学生类:只能有一个对象
class Student {
private String name;
private String sex;
boolean flag = false;
private static Student stu = new Student();
private Student() {
};
public static Student getStudent() {
return stu;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public static Student getStu() {
return stu;
}
public static void setStu(Student stu) {
Student.stu = stu;
}
}
// 设计存入数据线程
class Input implements Runnable {
Student s = Student.getStudent();
int x = 0;
@Override
public void run() {
while (true) {
synchronized (s) {
if (s.flag)
try {
s.wait();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (x == 0) {
s.setName("张三");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
s.setSex("男");
} else {
s.setName("lili");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
s.setSex("nvnvnnvnvnvnnv");
}
}
x = (x + 1) % 2;
s.flag = true;
s.notify();
}
}
}
// 设计输出线程
class Output implements Runnable {
Student s = Student.getStudent();
@Override
public void run() {
while (true)
synchronized (s) {
if (!s.flag)
try {
s.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(s.getName() + "-----" + s.getSex());
s.flag = false;
notify();
}
}
}
复制代码
作者:
sh1tge
时间:
2015-3-13 22:08
说几个明显的错误;
第一是你获取学生对象的时机不对
第二Input 类中 部分代码应该写进同步代码中 而你没有
第三output类中 notify 应该为 s.notify
第四while 循环少了个{
总之lz写代码的条理性有点乱...
顺便附上修改过后的
public class ThreadSave {
/**
* @param args
*/
public static void main(String[] args) {
Student s = Student.getStudent();
Thread t = new Thread(new Input(s));
Thread t1 = new Thread(new Output(s));
t.start();
t1.start();
}
}
// 饿汉式单例设计模式设计学生类:只能有一个对象
class Student {
private String name;
private String sex;
boolean flag = false;
private static final Student stu = new Student();
private Student() {
}
public static Student getStudent() {
return stu;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
// 设计存入数据线程
class Input implements Runnable {
private Student s;
Input( Student s){
this.s = s;
}
int x = 0;
@Override
public void run() {
while (true) {
synchronized (s) {
if (s.flag)
try {
s.wait();
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (x == 0) {
s.setName("张三");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
s.setSex("男");
} else {
s.setName("lili");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
s.setSex("nvnvnnvnvnvnnv");
}
x = (x + 1) % 2;
s.flag = true;
s.notify();
}
}
}
}
// 设计输出线程
class Output implements Runnable {
private Student s;
Output( Student s){
this.s = s;
}
@Override
public void run() {
while (true){
synchronized (s) {
if (!s.flag)
try {
s.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(s.getName() + "-----" + s.getSex());
s.flag = false;
s.notify();
}
}
}
}
复制代码
作者:
大神在何方
时间:
2015-3-13 23:39
看到那么多代码,以后我要是也会就好了。好怕自己学不会啊·感觉自己脑子不好使。会了成就感可大了
作者:
Jaybor
时间:
2015-3-14 08:56
如果你有多个输入输出线程还应该把if(flag)修改成while(flag),把notify修改成notifyAll()
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2