0

我有一个游戏可以创建漫无目的地在地图上游荡的“机器人”。每次玩家单击按钮时,都会创建一个新线程来创建机器人。如果您多次按下该按钮,则会生成许多具有相同线程名称 botThread 的机器人。

但是我希望能够区分机器人,以便我可以阻止单个机器人。所以我使用 setName() 函数将第一个机器人的名称更改为“Bot 1”,但是如果我尝试 Bot1.stop(),它说线程不存在?(我知道我不应该使用 .stop() 方法)。

但是,如果我在线程中遇到错误,它会显示“线程“Bot 1”中的异常”。所以它显然确实存在!

这是我的一些代码:

public class botGame{

Thread botThread;

public void newBot(){

botThread = new Thread(new Runnable(){

      public void run(){

             botThread.setName("Bot 1");
4

6 回答 6

5

线程名称只是调试代码的有用标识符。它与应用程序中的任何变量、对象或标识符完全无关。

换句话说: Callingthread.setName("foo")不会神奇让你 call foo.stop()

相反,您想要做的是保存Thread您在某个集合或映射中创建的对象,从那里检索它并随后对其进行操作(理想情况下使用stop(),如您所述)。

例如botThread,您将拥有以下内容,而不是单个字段:

Collection<Thread> botThreads = new ArrayList<Thread>();

当你启动一个线程时,你会这样做:

Thread botThread = new Thread( ... );
botThread.start();
botThreads.add(botThread);

而且由于我们的主题是避免停止:如果您不保留Thread对象,而是保留 a BotRunnable,则可以添加一个pleaseStop方法,BotRunnablevolatile boolean名为keepRunning(或类似)的字段设置为false. 然后,在run方法内部,定期检查该字段,如果是false,则简单地返回。

于 2013-04-16T12:18:24.613 回答
3

尝试将你的线程放在一个列表中,这样你就可以继续你想要的元素,然后删除它

于 2013-04-16T12:17:29.110 回答
1

你应该这样做:

public class botGame{
  Map<String, Thread> botThreads = new Map<String, Thread>();
  public void newBot(){
  Thread botThread = new Thread(new Runnable(){
    public void run(){
      }
    };
  botThreads.put("Bot 1", botThread);
}

我没有仔细检查我的示例是否有错误,而且您需要一种创建具有不同名称的线程的方法,但我认为您可以了解地图的想法。

要查找线程对象,请执行Thread thread = botThreads.get("Bot 1");

于 2013-04-16T12:25:02.190 回答
1

我的其他答案的一个更好的选择是让机器人跟踪他们自己的线程:

class Bot {
    Thread thread = null;
    private String name;
    volatile boolean stop = false;
    Bot(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void run() {
        thread = new Thread(new Runnable(){
            public void run(){
                while(!stop) {
                    ...
                }
            }
        };
        thread.start();
    }
    public void stop() {
        stop = true;
    }
}

在你的机器人创建代码中这样做:

public class botGame{
    Map<String, Bot> bots = new Map<String, Bot>();

    public void makeNewBot(String name) {
        bots.put(name, new(Bot(name)));
    }

    public void startBot(String name) {
        bots.get(name).run();  // TODO: Add check for wrong name
    }

    public void stopBot(String name) {
        bots.get(name).stop(); // TODO: Add check for wrong name
    }
}
于 2013-04-16T12:36:16.420 回答
0

除了使用线程名称之外,您还可以监视 Statefull 类或 Map 来授予线程运行或不运行的权限。

因此,一旦失去运行权限,您的线程就会自行结束。

于 2013-04-16T12:20:43.340 回答
-1

Thread.stop() 不应使用该方法 。它被弃用是有原因的—— 弃用的原因。在线程中使用volatile boolean标志来检查它是否应该停止。当你想停止它时,在主线程中设置标志。

于 2013-04-16T12:20:47.423 回答