我有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线程。
怎么做?
答案 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
...
}
换句话说:你必须跟踪那些处理得很好的线程;那些还没有准备好处理的东西。
注意:首先,上面的内容更像是“伪代码”,旨在让您前进。可能有各种方面需要仔细检查,例如:
getThreadByName()
方法看起来像一个肮脏,昂贵的黑客。如果跟踪您的线程在您的设计中非常重要,那么您应该为此创建一个真正的设计。例如,您的线程可能使用中央注册表,它可以保持简单的Map<String, Thread>
快速,定义明确的查找。