当前位置: 代码迷 >> Java相关 >> Java程序设计之合租房synchronized(2)
  详细解决方案

Java程序设计之合租房synchronized(2)

热度:64   发布时间:2016-04-22 19:53:05.0
Java程序设计之合租房synchronized(二)

  一号和二号合租一间房,里面共用一个卫生间对象,这是要用到synchronized关键字,一号与二号同时使用卫生间时,一个需要wait()等待被唤醒,另外一个使用完之后卫生间对象被释放,这时候刚刚使用的需要进入wait()状态,否则会造成死锁现象,卫生间资源释放之后,还需要唤醒另一个正在监听此对象的线程。

  首先构造一个房间类Room,内部构造一号和二号的对象,Object一个卫生间类,当作被线程监听的类,使用synchronized关键字:

synchronized (toliet) {}

  此时toliet对象被共享{}里面可以给一号和二号的使用操作,而同时该语句在run()方法里面,为了使一号和二号对象调用时不出现死锁。

  

 /*  * 一号和二号同租一间房,共同使用一个厕所,先刷牙,在小便,结束  */class Room extends Thread{    static Room p1 = new Room("一号");    static Room p2 = new Room("二号");        private String name;//代号        static Object toliet = new Object();        Room(String name){        this.name = name;    }    @Override    public void run() {        // TODO Auto-generated method stub        synchronized (toliet) {//只有获得卫生间的锁,才可以获得卫生间里面资源的使用            if(this.name.equals("一号")){                this.brush();                try {                    toliet.wait();  //刷牙完毕之后在门口等待被唤醒                    this.relase();//被唤醒之后开始小便,一号小便完之后要唤醒二号                    toliet.notify();                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }else{                this.brush();                toliet.notify();//让一号进来,自己等到被唤醒                try {                    toliet.wait();                    this.relase();                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        }    }        //刷牙的方法    public void brush(){        System.out.println(this.name+"正在刷牙");        try {            Thread.sleep(2000);        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        System.out.println(this.name+"刷牙完毕");    }        //解小便    public void relase(){        System.out.println(this.name+"正在小便");        try {            Thread.sleep(2000);        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        System.out.println(this.name+"小便完毕");    }}public class start {    public static void main(String[] args) {        // TODO Auto-generated method stub        Room.p1.start();        Room.p2.start();    }}

  很简单的synchronized关键字使用,两个线程共同监听一个对象,注意逻辑表达不要出现混乱,一个线程被唤醒,另一个立马进入wait()状态,上面是完整代码,同时要注意线程被唤醒,或者进入wait()状态,是共用对象唤醒正在监听的的线程和正在使用该对象的线程,比如:

                    toliet.wait();  //刷牙完毕之后在门口等待被唤醒                    this.relase();//被唤醒之后开始小便,一号小便完之后要唤醒二号                    toliet.notify();

  是<Object>toliet.wait()和toliet.notify(),如果此处用this,或者其他的线程对象代替,则会出现死锁。

  相关解决方案