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

问题描述 投票:0回答:1

我已经写了一些代码来同时通过两个线程遍历一个Thread-safe 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

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

java multithreading iterator hashtable
1个回答
2
投票

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

如果你在while循环之前创建迭代器,主线程也将返回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上进行迭代并不会阻止其他线程迭代它,就像你期望的那样。

© www.soinside.com 2019 - 2024. All rights reserved.