从另一个线程读取字段

时间:2015-07-14 14:52:26

标签: java multithreading field

我在学习java时正在创建一个基于TextBased的游戏。当我尝试从另一个Thread读取字段时,我遇到了问题。 睡眠班:

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

}

然后我从Menu类中调用方法“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();
    }
}

编辑: 对不起o忘了把一些课程。 人类:

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

1 个答案:

答案 0 :(得分:0)

这里发生的事情是,在Menu课程中,您要创建新的HungerSleep个对象,这些对象是独立的,与HungerSleep无关。在Human类中创建并运行的hunger个对象。

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

创建hunger对象时,您应该从sleep传递HumanMenu个对象,以便它可以访问它们。所以你需要改变你的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

现在您有一个hunger课程,可以从其他对象接收sleepHuman,您需要更改Menu menu = new Menu(); 中的以下行:

Menu menu = new Menu(hunger, sleep);

要:

Hunger

现在,创建的菜单可以访问Sleep内创建的Humansleep个对象。

但是也要将Sleep内的volatile更改为Menu,否则public volatile int sleep = 100; 可能无法正确显示!

Hunger

如果mainMenu中有类似的变量,请在那里执行相同的操作。

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