Java 从另一个线程读取字段
我在学习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);
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;