从另一个线程读取字段

Read Field from another Thread

我在学习的同时正在创建一个基于文本的游戏 java。当我尝试从另一个线程读取字段时遇到问题。 睡觉 Class:

package Events;

public class Sleep implements Runnable {

public int sleep = 100;

public void run() {
    while (true) {
        sleep--;
        System.out.println("Sleep: " + sleep);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (sleep == 50) {
            System.out.println("You need to eat");
        }
        if (sleep == 25) {
            System.out.println("You realy need to eat");
        }
        if (sleep == 10) {
            System.out.println("You'r almoust dying go to eat");
        }
        if (sleep == 0) {
            System.out.println("YOU'R DEAD");
        }
    }
}

public void PrintSleep() {
    System.out.println("Sleep: " + sleep);
}

}

然后我从菜单 class 调用方法 "PrintSleep" 并且应该出现 Sleep: 99 但出现 Sleep: 100

菜单 Class:

public class Menu {

Hunger hunger = new Hunger();
Sleep sleep = new Sleep();
Scanner scanner = new Scanner(System.in);

String answer;

public void MainMenu(){
    System.out.println("Main menu: 1 Home, 2 Work, 3 Shop, 4 Nessecity");

    answer = scanner.next();

    if(answer.equals("1")){ 
        HomeMenu();
    } else if(answer.equals("2")){
        WorkMenu();
    } else if(answer.equals("3")){
        ShopMenu();
    } else if(answer.equals("4")){          
        hunger.PrintHunger();
        sleep.PrintSleep();
    }
}

编辑: 抱歉 o 忘记输入一些 classes。 人类 class:

public class Human{

Hunger hunger = new Hunger();
Thread threadHunger = new Thread(hunger);
Sleep sleep = new Sleep();
Thread threadSleep = new Thread(sleep);

Menu menu = new Menu();
Scanner scanner = new Scanner(System.in);

private String name;
int money = 100;

public void CreateCharacter() {
    System.out.println("Type your name:");
    name = scanner.next();
    try {
        Thread.sleep(500);
    } catch (Exception e1) {
        e1.printStackTrace();
    }
    System.out.println("Your profile as been created with " + name + " name and " + money + " money.\n");
    try {
        Thread.sleep(500);
    } catch (Exception e2) {
        e2.printStackTrace();
    }

    threadHunger.start();
    threadSleep.start();
    menu.MainMenu();
}
}

主要class:

public class Game {

static Human human  = new Human();
public static void main(String[] args) {
    System.out.println("To start the game create your Human");
    human.CreateCharacter();
}
}

这里发生的是,在您的 Menu class 中,您正在创建新的 HungerSleep 对象,它们是独立的并且与在 Human class.

中创建的 HungerSleep 对象以及 运行

所以你正在通过线程创建一个人和 运行 他的 hungersleep,但是菜单看不到这些 hungersleep.它只能看到它自己创建的那些,而不是 运行.

当您创建 Menu 对象时,您应该将 Human 中的 hungersleep 对象传递给它,以便它可以访问它们。所以你需要像这样改变你的Menu

public class Menu {

    private final Hunger hunger; // Not initialized here but in the constructor
    private final Sleep sleep;   
    Scanner scanner = new Scanner(System.in);

    String answer;

    /**
     * Constructor that initializes the internal sleep and hunger
     * from values passed by whoever is creating and using it.
     *
     * @param hunger Hunger object passed from calling Human
     * @param sleep  Sleep object passed from calling Human
     */
    public Menu( Hunger hunger, Sleep sleep ) {
        this.hunger = hunger;
        this.sleep = sleep;
    }

    public void mainMenu(){
        System.out.println("Main menu: 1 Home, 2 Work, 3 Shop, 4 Nessecity");

        answer = scanner.next();

        if(answer.equals("1")){ 
            homeMenu();
        } else if(answer.equals("2")){
            workMenu();
        } else if(answer.equals("3")){
            shopMenu();
        } else if(answer.equals("4")){          
            hunger.printHunger();
            sleep.printSleep();
        }
    }
}

现在您有一个可以从另一个对象接收 hungersleepMenu class,您需要将以下行从 Human:

Menu menu = new Menu();

收件人:

Menu menu = new Menu(hunger, sleep);

现在创建的菜单可以访问在 Human.

中创建的 HungerSleep 对象

还要把Sleep里面的sleep改成volatile,否则Menu可能显示不正确!

public volatile int sleep = 100;

如果您在 Hunger 中有类似的变量,请在那里做同样的事情。

注意:我把方法的名字改成了mainMenu而不是MainMenu,还有里面调用的其他方法的名字.方法名称和变量名称应始终以小写字母开头。只有类型名称(classes、接口、枚举)应该以大写字母开头。