【问题标题】:Stopping a specific java thread停止特定的 java 线程
【发布时间】:2011-12-08 20:02:43
【问题描述】:

我有一个按钮“addCashier”,它正在创建一个名为“Cashier”的线程,现在这个线程只是简单地每 4 秒生成一次订单,线程的 run() 方法中有一个 while(true) 循环。那里一切都很好,但现在我想添加一个按钮来模拟收银员注销。我在我的 while 循环 onDuty 和一个公共函数 logOff() 中添加了一个布尔变量,它将这个 onDuty bool 设置为 false 以使我退出运行的 while 循环。我现在的问题来自我的 gui 类,如何在特定线程上调用函数?每个收银员线程都是在运行时生成的,所以我不知道他们的名字。

我希望我说得通。提前致谢。

【问题讨论】:

  • 这取决于您创建线程的方式。可以通过数组引用吗?
  • hmmm 我不知道你可以将线程对象存储在一个数组中,我来看看这种方法。
  • @mikeyP - 你也可以将它们保存在HashMap<String, Thread>;你提到他们有一些“名字”,这将是 (String) 键。
  • @BrianRoach 好的,这是有道理的,我喜欢 Hash 实现,但是在这段代码中,线程引用会是 myThread:Thread myThread; Cahier (String name) { myThread = new Thread( this ); myThread.start(); }
  • @mikeyP,没错-myThread 是您的参考-但您还需要通过在每个线程的Thread 参考上调用setName(String name) 方法来明确设置Thread 的名称你创造。然后将两者(名称和引用)添加到 HashMap 中。使用Name 作为句柄,以便稍后让您的线程停止特定线程。

标签: java multithreading


【解决方案1】:
Thread t = CashierThread();  //keep the reference to thread somewhere...

现在使用内置中断标志代替布尔属性:

public void run() {
  while(!Thread.currentThread().isInterrupted()) {
    //...
  }
}

当您想通过单击按钮关闭线程时,只需调用:

t.interrupt();

当然,您需要从客户端代码访问t 变量。

【讨论】:

  • +1:虽然正确,但我会选择较短的while(!Thread.interrupted()),假设我只是要退出线程。
  • 虽然这是停止线程的一种方法,但它对他现有的布尔解决方案没有任何作用。他真正的问题是他没有跟踪他的线程,也不知道如何找到它们来阻止它们。
  • 好的,谢谢 Tomasz 和其他人。现在只是想弄清楚如何获取此线程参考。
  • @TomaszNurkiewicz 如果我做了类似Thread myThread; Cahier (String name) { myThread = new Thread( this ); myThread.start(); } 之类的事情,myThread 会是参考吗?
  • @BrianRoach:同意,所以我想我的第一条评论:在某处保留对线程的引用实际上回答了这个问题。其余的实际上是建议不要使用手工制作的标志(并避免同步/易失性陷阱)。但我现在看到其他推荐地图数据结构的答案更准确一些,现在支持它们:-)。
【解决方案2】:

您可以将每个线程的引用存储到 HashMap 中 - 连同其 idName 作为键。稍后当您想要处理一个特定的 Cashier 线程时,使用 Nameid 从 HashMap 中获取相应的 Thread 并在其上调用相应的 logOff() 方法。

【讨论】:

    【解决方案3】:

    如果收集对所有线程的引用是一个问题,另一种方法可能是拥有一个公共静态同步 HashMap,其中 threadId(在运行时分配给每个线程的随机数)作为键,布尔值作为值。您可以修改 while 循环以从此集中式 Map 中选择相应的布尔值。这可以让您注销特定的收银员。

    【讨论】:

      【解决方案4】:

      您可以在某处保留 Thread 对象的引用,以便您可以调用 threadObj.logOff()

      如果您不愿意这样做,那么在创建线程时,您可以为线程分配一个唯一的名称。

      public void run ()
      {
          this.setName(strCashireID);
          ......
      }
      

      在运行时,你可以通过以下方式获取线程:

      Thread getThread(String strCashireID) {
         ThreadGroup threadGroup = Thread.currentThread( ).getThreadGroup( );
         Threads[] threads = new Thread[ threadGroup.activeCount() ];
         threadGroup.enumerate(threads);
         for (int nIndex=0; nIndex<threads.length; nIndex++) {
            if(threads[nIndex] != null && threads.getName().equals(strCashireID) {
               return threads[nIndex];
            }
         }
         return null;
      }
      

      我仍然建议你将线程对象存储在哈希映射中,而不是在运行时枚举它们。

      【讨论】:

        猜你喜欢
        • 2020-08-28
        • 1970-01-01
        • 2013-04-19
        • 1970-01-01
        • 1970-01-01
        • 2012-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多