Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从另一个线程读取字段_Java_Multithreading_Field - Fatal编程技术网

Java 从另一个线程读取字段

Java 从另一个线程读取字段,java,multithreading,field,Java,Multithreading,Field,我在学习java时正在创建一个基于文本的游戏。当我试图从另一个线程读取一个字段时,我遇到了一个问题。 睡眠课: package Events; public class Sleep implements Runnable { public int sleep = 100; public void run() { while (true) { sleep--; System.out.println("Sleep: " + sleep);

我在学习java时正在创建一个基于文本的游戏。当我试图从另一个线程读取一个字段时,我遇到了一个问题。 睡眠课:

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);
}

}
然后我从菜单类调用方法“PrintSleep”,应该显示Sleep:99,但显示Sleep:100

菜单类:

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();
    }
}
编辑: 很抱歉,我忘了给你上几节课。 人类阶级:

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();
}
}
主要类别:

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();
}
}

这里发生的事情是,在
菜单
类中,您正在创建新的
饥饿
睡眠
对象,它们是独立的,与
饥饿
睡眠
对象无关,这些对象是在
人类
类中创建和运行的

因此,您正在创建一个人,并通过线程运行他的
饥饿
睡眠
,但菜单没有看到这些
饥饿
睡眠
。它只看到它自己创建的那些,它们没有运行

创建
菜单
对象时,应将
人类
中的
饥饿
睡眠
对象传递给它,以便它可以访问它们。因此,您需要更改
菜单,如下所示:

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();
        }
    }
}
现在您有了一个
菜单
类,可以从另一个对象接收
饥饿
睡眠
,您需要从
人类
更改以下行:

Menu menu = new Menu();
致:

现在,所创建的菜单可以访问在
人类
中创建的
饥饿
睡眠
对象

但也要将
sleep
内部的
sleep
更改为
volatile
,否则
菜单可能无法正确显示

public volatile int sleep = 100;
如果在
饥饿
中有类似的变量,请在那里执行相同的操作


注意:我将该方法的名称改为
main menu
,而不是
main menu
,以及在其中调用的其他方法的名称。方法名和变量名应始终以小写字母开头。只有类型名(类、接口、枚举)应该以大写字母开头。

您是否尝试过将
volatile
修饰符添加到
sleep
变量?您从未调用
sleep.run()
或将其传递给线程并启动该线程(通常使用
Runnable
)。因此,内部
sleep
计数器仍然是100。您需要创建一个线程(使用sleep类)并启动它以执行
run
方法。
public volatile int sleep = 100;