死锁|线程之间的交互,wait和notify

A线程占用对象盖伦

B线程占用对象提莫

A试图占用提莫,等待B释放cpu资源

B同理

相互等待,GG

—————————————————————————————————————————————————————————

同样加血减血

当hurt hp==1时就要停止,当血量加上去了才能继续hurt

怎么处理?

t1(关于hurt的线程)里面run覆盖,while(1)里面每次hp--,再while(hp==1),continue

将t1的线程频率提高来达到肯定会出现ho==1的情况

可以用set,或者sleep,阻塞时间相对少些就更多的被调度

BUT,这个方法小号cpu太大,性能太低下

这个时候,出现了wait与notify

思路就是,最开始t1占用,但是hp==1时,wait,这个时候cpu资源释放出来调度t2的recover加血,加好了notify

就通知等待在this对象上的进程可以醒过来开始工作了

需要注意的时wait()的使用一定在synchronized的块里面,因为就是因为这个线程独占了this其他进程才不能工作

然后wait()让他让出cpu,让出对象,其他线程再来,其他线程玩够了,OK,notify,你又继续

....

这个过程太狗血了..

Hero类:两个啊方法

 public synchronized void recover() {
        hp = hp + 1;
        System.out.printf("%s 回血1点,增加血后,%s的血量是%.0f%n", name, name, hp);
        // 通知那些等待在this对象上的线程,可以醒过来了,如第20行,等待着的减血线程,苏醒过来
        this.notify();
    }
 
    public synchronized void hurt() {
        if (hp == 1) {
            try {
                // 让占有this的减血线程,暂时释放对this的占有,并等待
                this.wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
 
        hp = hp - 1;
        System.out.printf("%s 减血1点,减少血后,%s的血量是%.0f%n", name, name, hp);
    }

Teetthread类

Thread t1 = new Thread(){
            public void run(){
                while(true){
                       
                    //无需循环判断
//                    while(gareen.hp==1){
//                        continue;
//                    }
                       
                    gareen.hurt();//不等于1直接hurt,等于1进入内层循环continue hurt中又让其wait

                     
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
   
            }
        };
        t1.start();
   
        Thread t2 = new Thread(){
            public void run(){
                while(true){
                    gareen.recover();//t2执行让他加血,然后notify//起初执行没那么快,因为sleep的原因
   
                    try {
                        Thread.sleep(100);

                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
   
            }
        };
        t2.start();
             
    }

猜你喜欢

转载自blog.csdn.net/Whiteleaf3er/article/details/82661398