You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取类结束时变量的最终值及跨类访问该值?

解决方案:30秒后获取并访问Game类的变量最终值

针对你的两个问题,我结合现有代码给出调整方案,解决死循环、定时停止、变量获取和跨类访问的问题:


1. 让Game类在30秒后结束并获取变量最终值

你的现有代码里Game构造函数是死循环while(true),定时器无法终止它,所以首先要添加一个线程安全的停止标志,让定时器能通知Game停止循环,之后就能在循环结束后打印变量。

修改后的Game类:

import java.io.IOException;

public class Game {
    // volatile保证多线程下可见性,定时器线程修改后主线程能立刻看到
    private volatile boolean isRunning = true;
    private int true_num = 0, false_num = 0; // 建议封装,用getter访问

    public Game() throws InterruptedException, IOException {
        // 把Game实例传给TimerDemo,让定时器能通知停止
        new TimerDemo(30, this);
        
        while (isRunning) {
            play();
            Thread.sleep(100); // 加个小休眠,避免CPU空转
        }
        
        // 循环结束后,打印最终值
        printFinalValues();
    }

    private void play() {
        // 模拟变量变化逻辑,你可以替换成自己的代码
        if (Math.random() > 0.5) true_num++;
        else false_num++;
    }

    // 供定时器调用,停止循环
    public void stopGame() {
        isRunning = false;
    }

    private void printFinalValues() {
        System.out.println("=== 程序运行结束 ===");
        System.out.println("true_num最终值: " + true_num);
        System.out.println("false_num最终值: " + false_num);
    }

    // 提供getter方法,供其他类访问变量
    public int getTrueNum() {
        return true_num;
    }

    public int getFalseNum() {
        return false_num;
    }
}

对应的TimerDemo类修改,让它能触发Game停止:

import java.awt.Toolkit;
import java.util.Timer;
import java.util.TimerTask;

public class TimerDemo {
    Toolkit toolkit;
    Timer timer;
    private Game gameInstance;

    public TimerDemo(int seconds, Game game) {
        this.gameInstance = game;
        toolkit = Toolkit.getDefaultToolkit();
        timer = new Timer();
        
        // 延迟指定秒数后执行停止任务
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                gameInstance.stopGame();
                timer.cancel(); // 取消定时器,释放资源
            }
        }, seconds * 1000);
    }
}

2. 从另一个类访问Game的变量最终值

有两种常用方式,根据你的场景选择:

方式一:直接通过Game实例的getter访问

如果你的调用类可以等待Game运行结束,直接在Game构造完成后调用getter方法即可:

public class GameViewer {
    public static void main(String[] args) {
        try {
            Game game = new Game();
            // Game构造函数会阻塞到30秒结束,之后可以直接获取值
            System.out.println("\n--- 从GameViewer访问的最终值 ---");
            System.out.println("true_num: " + game.getTrueNum());
            System.out.println("false_num: " + game.getFalseNum());
        } catch (InterruptedException | IOException e) {
            e.printStackTrace();
        }
    }
}

方式二:观察者模式(异步监听)

如果其他类不想阻塞等待,而是希望Game结束时主动通知,可以用观察者模式:

首先定义一个监听接口:

public interface GameEndListener {
    void onGameFinished(int trueNum, int falseNum);
}

修改Game类,添加监听列表和通知逻辑:

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class Game {
    private volatile boolean isRunning = true;
    private int true_num = 0, false_num = 0;
    private List<GameEndListener> endListeners = new ArrayList<>();

    public Game() throws InterruptedException, IOException {
        new TimerDemo(30, this);
        
        while (isRunning) {
            play();
            Thread.sleep(100);
        }
        
        // 通知所有注册的监听器
        notifyGameEnd();
        printFinalValues();
    }

    // 添加注册监听器的方法
    public void addGameEndListener(GameEndListener listener) {
        endListeners.add(listener);
    }

    private void notifyGameEnd() {
        for (GameEndListener listener : endListeners) {
            listener.onGameFinished(true_num, false_num);
        }
    }

    // 其他方法不变...
}

然后实现监听器的类:

public class AsyncGameMonitor implements GameEndListener {
    public static void main(String[] args) {
        try {
            Game game = new Game();
            // 注册监听器
            game.addGameEndListener(new AsyncGameMonitor());
            // 这里可以执行其他任务,不用等待30秒
            System.out.println("正在后台监控Game运行...");
        } catch (InterruptedException | IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onGameFinished(int trueNum, int falseNum) {
        System.out.println("\n--- AsyncGameMonitor收到结束通知 ---");
        System.out.println("true_num最终值: " + trueNum);
        System.out.println("false_num最终值: " + falseNum);
    }
}

关键注意点

  • volatile关键字:必须用它修饰停止标志isRunning,因为定时器的任务是在独立线程执行的,volatile能保证主线程及时看到标志的变化,避免死循环。
  • 封装变量:把true_num和false_num改成private,用getter方法访问,符合面向对象的封装原则,也能方便后续添加线程安全控制。
  • 避免CPU空转:在循环里加Thread.sleep(100),防止程序占用过高CPU资源。

内容的提问来源于stack exchange,提问作者ParisaN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:35:38