【问题标题】:Why Parent thread does not gets executed after Child Thread?为什么父线程在子线程之后没有被执行?
【发布时间】:2019-03-23 07:52:17
【问题描述】:

我编写了一些代码来同时通过两个线程遍历线程安全的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

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

【问题讨论】:

  • 你需要设置it 你填充Hashtable,否则你有一个迭代器到Hashtable的末尾hasNext为假.
  • 您的迭代器是在地图没有元素时创建的,因此它的第一个 hasNext() 返回 false,或者它抛出了 ConcurrentModificationException。这不是有效的使用模式。

标签: java multithreading iterator hashtable


【解决方案1】:

您的代码的第一个问题是您在将任何条目添加到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 并不会阻止其他线程像您预期的那样对其进行迭代。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 2021-07-23
    • 1970-01-01
    相关资源
    最近更新 更多