2 greetings2016 Greetings2016 于 2016.02.28 20:49 提问

初学java多线程 遇到点问题望各位前辈不吝赐教

/*张三先洗漱,然后让李四洗漱 李四洗刷完让张三上厕所 张三上完厕所 让李四上厕所
**/
static MyRoomThread zhangsan = new MyRoomThread("张三");
static MyRoomThread lisi = new MyRoomThread("李四");

String name ;
Object toliet = new Object();

MyRoomThread(String name) {
this.name = name;
}

@Override
public void run() {
try {
synchronized (toliet) {
if (this.name.equals("张三")) {
this.Brush();
toliet.wait();
this.release();
toliet.notify();

}else {
this.Brush();
toliet.wait();;
toliet.notify();
this.release();

}
}
}catch (Exception e) {
e.printStackTrace();
}

}
//洗漱的方法
public void Brush() throws Exception {
System.out.println(this.name+"上厕所,刷牙ing。。。");
Thread.sleep(2000);
System.out.println(this.name+"刷牙完毕,离开厕所。。。");
}
//上厕所的方法
public void release() throws Exception {
System.out.println(this.name+"在上厕所,正在小便ing。。。");
Thread.sleep(2000);
System.out.println(this.name+"小便完毕,离开厕所");
}
}
public >
public static void main(String[] args) {
MyRoomThread.zhangsan.start();
MyRoomThread.lisi.start();

}

}

3个回答

wojiushiwo945you
wojiushiwo945you   Ds   Rxr 2016.02.29 06:39
已采纳

你的代码有问题,你的每个线程对象都有一个Object toliet = new Object();加锁都是在自己成员属性上,锁不同,当然不能有互斥访问了。就好比每个人都在自己家,用的都是自己家的toilet,当然会出现4个人同时都在自己家的toilet的现象啊。你要把这个toilet变成火车上公共的。
你应该保证所有线程运行run时对共享变量的访问用的是同一个锁对象,然能实现互斥效果。

wojiushiwo945you
wojiushiwo945you   Ds   Rxr 2016.02.29 06:51

给你个正确互斥访问的版本,你试试:

 public class MyRoomThread extends Thread {
    String name;
    Object toliet;

    MyRoomThread(String name,Object toilet) {
        this.name = name;
        this.toliet = toilet;
    }

    @Override
    public void run() {
        try {
            synchronized (toliet) {
                if (this.name.equals("张三")) {
                    this.Brush();
                    toliet.wait();
                    this.release();
                    toliet.notify();

                } else {
                    this.Brush();
                    toliet.wait();
                    ;
                    toliet.notify();
                    this.release();

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    // 洗漱的方法
    public void Brush() throws Exception {
        System.out.println(this.name + "上厕所,刷牙ing。。。");
        Thread.sleep(2000);
        System.out.println(this.name + "刷牙完毕,离开厕所。。。");
    }

    // 上厕所的方法
    public void release() throws Exception {
        System.out.println(this.name + "在上厕所,正在小便ing。。。");
        Thread.sleep(2000);
        System.out.println(this.name + "小便完毕,离开厕所");
    }

    public static void main(String[] args) {
         Object publicToilet = new Object();
         MyRoomThread zhangsan = new MyRoomThread("张三",publicToilet);
         MyRoomThread lisi = new MyRoomThread("李四",publicToilet);
         zhangsan.start();
         lisi.start();
    }
}

运行结果,有互斥等待现象:

张三上厕所,刷牙ing。。。
张三刷牙完毕,离开厕所。。。
李四上厕所,刷牙ing。。。
李四刷牙完毕,离开厕所。。。
Greetings2016
Greetings2016 你好 十分感谢你的纠正 但是你写的程序无法运行上厕所小便的方法了 我不知道哪里出了问题
接近 2 年之前 回复
Greetings2016
Greetings2016 上厕所的那个方法总是显示不出来 是不是死锁了呢?
接近 2 年之前 回复
Mr_dsw
Mr_dsw   Ds   Rxr 2016.02.28 23:07

遇到的是线程不同步吧?刚学这块都这样

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!