等待创建线程并跳过已完成执行的线程

时间:2016-11-25 14:04:01

标签: java multithreading

我有4个主题,比如A,B,C和D. D取决于所有3个线程。 A,B和C. 它应该只在所有3个其他线程完成执行后才开始。

在D

的运行方法中
    public void run() {

            for ( final String name : nameList ) {
                final Thread thread = getThreadByName( name );
                if ( thread != null ) {
                    while ( thread.isAlive() ) {
                        thread.join();
                    }
                }

            }
       //Do something
     }

nameList包含线程A,B和C的名称。

get thread by name方法看起来像

public Thread getThreadByName( String threadName ) {
    for ( final Thread t : Thread.getAllStackTraces().keySet() ) {
        if ( t.getName().equals( threadName ) ) {
            return t;
        }
    }
    return null;
}

在我的情况下,线程A已被执行且线程B正在进行中,线程C尚未提交。

当提交线程D时,它尝试按名称获取线程A,它返回null,然后跳过它并尝试按名称获取线程B,它返回线程B.线程D等待B完成然后检查线程C. getThreadByName为C返回null,因为C的线程尚未提交。线程D跳过它并开始执行//Do something

中的更多代码

我希望线程D也等待线程C. 它应该跳过线程A,因为它已经完成。 等待它正在做的线程B. 但它也应该等待C线程。

怎么做?

1 个答案:

答案 0 :(得分:0)

for 循环只会在数据集上迭代一次。你需要不同的东西;像这样:

Set<String> threadsToMonitoryByName = ... 

while (! threadsToMonitoryByName.empty() ) {
  for (String threadName : threadsToMonitorByName) { 
     Thread thread = getThreadByName( threadName );
       if ( thread != null ) {
         while ( thread.isAlive() ) {
            thread.join();
            threadsToMonitorByName.remove(threadName);
         }
      }
  }
  // and probably some thread sleeping here to avoid HOT waiting
  ...
}

换句话说:你必须跟踪那些处理得很好的线程;那些还没有准备好处理的东西。

注意:首先,上面的内容更像是“伪代码”,旨在让您前进。可能有各种方面需要仔细检查,例如:

  1. 在封闭的while循环中使用for循环只需一种方式。您也可以选择字符串列表的第一个元素;只是工作。这里有很多选择!
  2. 我不确定您是否可以迭代该Set的条目...同时从集合中删除元素。
  3. 正如HRgiger所指出的那样:在调用join()
  4. 之前,你可能不需要检查isAlive()。
  5. 可能最有问题的是:你的getThreadByName()方法看起来像一个肮脏,昂贵的黑客。如果跟踪您的线程在您的设计中非常重要,那么您应该为此创建一个真正的设计。例如,您的线程可能使用中央注册表,它可以保持简单的Map<String, Thread>快速,定义明确的查找。