Java 等待线程创建并跳过已完成执行的线程
我有4个线程,比如A、B、C和D。 D依赖于所有3个线程。A、 B和C。 它应该只在所有其他3个线程完成执行后启动 D的运行方法Java 等待线程创建并跳过已完成执行的线程,java,multithreading,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 ) {
public void run() {
for ( final String name : nameList ) {
final Thread thread = getThreadByName( name );
if ( thread != null ) {
while ( thread.isAlive() ) {
thread.join();
}
}
}
//Do something
}
名称列表包含线程A、B和C的名称
按名称获取线程方法如下所示
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
如何做到这一点?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
...
}
设置threadsToMonitoryByName=。。。
而(!threadsToMonitoryByName.empty()){
对于(字符串threadName:threadsToMonitorByName){
Thread-Thread=getThreadByName(threadName);
if(线程!=null){
while(thread.isAlive()){
thread.join();
threadsToMonitorByName.remove(threadName);
}
}
}
//可能是一些线程睡在这里,以避免热等待
...
}
换句话说:你必须跟踪那些处理得很好的线程;还有那些还没有准备好处理的
注意:首先,上面的内容更像是“伪代码”,旨在让您继续。可能有许多方面需要仔细检查,例如:
getThreadByName()
方法看起来像是一个肮脏、昂贵的黑客。如果跟踪你的线程在你的设计中很重要,那么你应该为此创建一个真正的设计。例如,您的线程可能使用一个中央注册表,该注册表保存一个简单的映射
,以便进行快速、定义良好的查找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
...
}
设置threadsToMonitoryByName=。。。
而(!threadsToMonitoryByName.empty()){
对于(字符串threadName:threadsToMonitorByName){
Thread-Thread=getThreadByName(threadName);
if(线程!=null){
while(thread.isAlive()){
thread.join();
threadsToMonitorByName.remove(threadName);
}
}
}
//可能是一些线程睡在这里,以避免热等待
...
}
换句话说:你必须跟踪那些处理得很好的线程;还有那些还没有准备好处理的
注意:首先,上面的内容更像是“伪代码”,旨在让您继续。可能有许多方面需要仔细检查,例如:
getThreadByName()
方法看起来像是一个肮脏、昂贵的黑客。如果跟踪你的线程在你的设计中很重要,那么你应该为此创建一个真正的设计。例如,您的线程可能使用一个中央注册表,该注册表保存一个简单的映射
,以便进行快速、定义良好的查找您需要运行while循环来使用join吗?这是他的代码;我试着尽可能地匹配。但我会在答案中补充这一点;谢谢
entries()
是Set
界面中的方法吗?Java 7中没有列出它:我还担心在对集合进行迭代时修改它。@AndrewHenle非常感谢您。。。这就是我为什么写伪代码的原因。你完全正确,因为这是一个集合,而不是一张地图,一个人只是“走”集合本身。你的第二点已经在我的笔记中提到了。@GhostCat跟踪线程为我工作。我还更改了getThreadByName()方法。谢谢:)使用join需要运行while循环吗?这是他的代码;我试着尽可能地匹配。但我会在答案中补充这一点;谢谢entries()
是Set
界面中的方法吗?Java 7中没有列出它:我还担心在对集合进行迭代时修改它。@AndrewHenle非常感谢您。。。这就是我为什么写伪代码的原因。你完全正确,因为这是一个集合,而不是一张地图,一个人只是“走”集合本身。你的第二点已经在我的笔记中提到了。@GhostCat跟踪线程为我工作。我还更改了getThreadByName()方法。谢谢:)也许java.util.concurrent.CountDownLatch
-我从来没用过它。。。另外,请看一下java.util.concurrent.CyclicBarrier
和java.util.concurrent.Semaphore
。我今天给大家的答案是。。。是朱