为什么父线程在子线程之后不执行?

Why Parent thread does not gets executed after Child Thread?

我已经编写了一些代码来通过两个线程同时遍历线程安全 Hashtable。预计一次只有一个线程可以从以下代码中读取-

class Test7 extends Thread{
static Hashtable t=new Hashtable();
static Iterator it=t.entrySet().iterator();

public static void main(String[] args) throws InterruptedException{
    t.put(1,"a");
    t.put(2,"b");
    t.put(3,"c");
    t.put(4,"d");
    t.put(5,"e");

    Test7 q=new Test7();
    q.start();

    while(it.hasNext()){
        out.println("Parent thread");
        Map.Entry m1=(Map.Entry)it.next();
        out.println(m1);
        Thread.sleep(2000);
    }
}

public void run(){
    Iterator it=t.entrySet().iterator();

    while(it.hasNext()){
        out.println("Child thread");
        Map.Entry m2=(Map.Entry)it.next();
        out.println(m2);
        try{
            Thread.sleep(2000);
        }
        catch(InterruptedException e){
            out.println(1);
        }
    }
}
}

程序终止后的输出-

Child thread
5=e
Child thread
4=d
Child thread
3=c
Child thread
2=b
Child thread
1=a

为什么父线程在这之后不执行?任何线索都会有所帮助,我们将不胜感激。

您的代码的第一个问题是您在将任何条目添加到 Hashtable 之前为主线程创建了迭代器。对于这种特殊情况,entrySet().iterator() 方法 return 是一个 java.utils.Collections.EmptyIterator,其 hasNext() 方法始终 return false。

如果您要在 while 循环之前创建迭代器,主线程也会 return 来自 Hashtable:

的条目
it=t.entrySet().iterator();
while(it.hasNext()){
    out.println("Parent thread");
    //...
}

但是这只会导致交错输出:

Parent thread
Child thread
5=e
5=e
Child thread
4=d
Parent thread
4=d
Child thread
3=c

为什么?因为虽然 Hashtable(如 putputAllgetsize 等)的访问方法是同步的,但您可以创建的迭代器 一般不同步,remove方法除外。

特别是对 Hashtable 的迭代并不会像您预期的那样阻止其他线程对其进行迭代。