停止重命名的Thread

时间:2013-04-16 12:14:41

标签: java multithreading

我有一个游戏,创造了'机器人'漫无目的地漫游在地图上。每次玩家点击按钮时,都会创建一个创建机器人的新线程。如果您多次按下按钮,则会使用相同的线程名称botThread创建多个机器人。

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

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

以下是我的一些代码:

public class botGame{

Thread botThread;

public void newBot(){

botThread = new Thread(new Runnable(){

      public void run(){

             botThread.setName("Bot 1");

6 个答案:

答案 0 :(得分:5)

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

换句话说:拨打thread.setName("foo") 会神奇地允许您拨打foo.stop()

您想要做的是保留您在某个集合或地图中创建的Thread个对象,然后从那里检索并操纵它(理想情况下使用stop() ,正如你所指出的那样。)

例如,您可以使用以下内容代替单个botThread字段:

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

当你开始一个线程时,你会这样做:

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

由于我们的主题是避免停止:如果你没有坚持Thread对象,而是坚持BotRunnable,你可以添加pleaseStop方法BotRunnable将名为volatile boolean(或类似)的keepRunning字段设置为false。然后,在run方法内,定期检查该字段,如果是false,则只需返回。

答案 1 :(得分:3)

尝试将您的线程放在一个列表中,这样您就可以继续使用所需的元素并将其删除

答案 2 :(得分: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");

答案 3 :(得分: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
    }
}

答案 4 :(得分:0)

您可以监视Statefull类或Map,而不是使用线程名称,这样可以为线程提供运行权限。

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

答案 5 :(得分:-1)

不应使用方法Thread.stop() 。它被弃用是有原因的 - deprecation reason。在线程中使用volatile boolean标志来检查它是否应该停止。如果要停止,请在主线程中设置标志。