黑马程序员技术交流社区
标题:
多线程synchronized问题
[打印本页]
作者:
赵庆礼
时间:
2012-6-24 23:49
标题:
多线程synchronized问题
本帖最后由 赵庆礼 于 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();
}
}
这是我看完毕老师的视频,按照毕老师的思路写的,但是不对,大侠帮忙看看哪儿出错了。
作者:
周兴中
时间:
2012-6-25 00:21
本帖最后由 周兴中 于 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();
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2