首页 新闻 会员 周边 捐助

Java,3个减血线程join在3个加血线程前,为什么英雄血量输出会不匹配

1
[待解决问题]

预想:

盖伦减血1点,现在盖伦的hp是: 99.0
盖伦减血1点,现在盖伦的hp是: 97.0
盖伦减血1点,现在盖伦的hp是: 98.0
盖伦的血恢复1点,现在盖伦的hp是:99.0
盖伦的血恢复1点,现在盖伦的hp是:100.0
盖伦的血已满!

结果:

盖伦减血1点,现在盖伦的hp是: 99.0
盖伦减血1点,现在盖伦的hp是: 97.0
盖伦减血1点,现在盖伦的hp是: 98.0
盖伦的血恢复1点,现在盖伦的hp是:99.0
盖伦的血恢复1点,现在盖伦的hp是:100.0
盖伦的血恢复1点,现在盖伦的hp是:98.0

这两个线程组之间有什么匹配问题?

代码:

TestHero.java

public class TestHero {
    public static void main(String[] args) {
        Hero gareen = new Hero("盖伦", 100, 10);
        int N = 3;
        Thread[] hurtThreads = new Thread[N];
        Thread[] coverThreads = new Thread[N];

        for (int i = 0; i < N; i++) {
            Thread t1 = new Thread(() -> {
                gareen.hurt();
                System.out.println("盖伦减血1点,现在盖伦的hp是: " + gareen.hp);
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            });
            t1.start();
            hurtThreads[i] = t1;
        }
        for(Thread t : hurtThreads) {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        for(int j = 0; j < N; j++){
            Thread t2 = new Thread(() -> {
                    gareen.recover();
                    System.out.println("盖伦的血恢复1点,现在盖伦的hp是:"+ gareen.hp);
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

            });
            t2.start();
            coverThreads[j] = t2;
        }


    }
}



Hero.java

import java.io.Serializable;

public class Hero{
    public String name;
    public float hp;
    public int damage;

    public Hero(){
        
    }
    public Hero(String name,float hp,int damage){
        this.name = name;
        this.hp = hp;
        this.damage = damage;
    }

//    伤害和恢复这两个线程同时只能有一个线程在执行
    public synchronized void hurt(){
            if(hp == 1){
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.hp -= 1;
            this.notify();
    }

    public synchronized void recover(){
            if(hp == 1000){
                System.out.println(this.name + "的血已满!");
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.hp += 1;
            this.notify();
    }

    public void attackHero(Hero h) {
        try {
            //为了表示攻击需要时间,每次攻击暂停1000毫秒
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        h.hp-=damage;
        System.out.format("%s 正在攻击 %s, %s的血变成了 %.0f%n",name,h.name,h.name,h.hp);

        if(h.isDead())
            System.out.println(h.name +"死了!");
    }

    public boolean isDead() {
        return 0>=hp?true:false;
    }

}
另一种开始的主页 另一种开始 | 初学一级 | 园豆:119
提问于:2021-09-24 23:32

recover() 中,1000 是什么意思?

快乐的凡人721 3年前

@快乐的凡人721: 盖伦初始Hp是100,原本我要改成1000的,recover的1000意思是加血到了1000的时候就会中止线程,等到被减血了再加血,不过这不影响阅读

另一种开始 3年前
< >
分享
所有回答(1)
0

结果没问题呀,在执行recover的三个线程之前,由于join方法,可以保证当时盖伦的血量是97,所以recover的三个线程不就是98,99,100,由于三个线程不是顺序执行的,所以
盖伦的血恢复1点,现在盖伦的hp是:99.0
盖伦的血恢复1点,现在盖伦的hp是:100.0
盖伦的血恢复1点,现在盖伦的hp是:98.0
这三句话以任何顺序输出都有可能呀。

小马群 | 园豆:204 (菜鸟二级) | 2022-06-14 15:59
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册