Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么父线程不在子线程之后执行?_Java_Multithreading_Iterator_Hashtable - Fatal编程技术网

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

Java 为什么父线程不在子线程之后执行?,java,multithreading,iterator,hashtable,Java,Multithreading,Iterator,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");

我已经编写了一些代码,通过两个线程同时遍历线程安全的哈希表。预计一次只能有一个线程从下面的代码中读取-

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

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

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

如果要在while循环之前创建迭代器,则主线程还将从
哈希表返回条目:

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
为什么??因为虽然
哈希表
的访问方法(如
put
putAll
get
size
等)是同步的,但是您可以创建的迭代器一般不同步,除了
删除
方法


尤其是在
哈希表上迭代
并不能阻止其他线程像您预期的那样在其上迭代。

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

如果要在while循环之前创建迭代器,则主线程还将从
哈希表返回条目:

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
为什么??因为虽然
哈希表
的访问方法(如
put
putAll
get
size
等)是同步的,但是您可以创建的迭代器一般不同步,除了
删除
方法


尤其是在
哈希表上迭代
并不能阻止其他线程像预期的那样在其上迭代。

在填充
哈希表
之后,需要设置
,否则,在
哈希表
的末尾有一个迭代器,
hasNext
为false。迭代器是在映射没有元素时创建的,因此它的第一个
hasNext()
返回false,或者它抛出了一个
ConcurrentModificationException
。这不是有效的使用模式。您需要在填充
哈希表
后设置
,否则在
哈希表
的末尾有一个迭代器,其上的
hasNext
为false。迭代器是在映射没有元素时创建的,因此它的第一个
hasNext()
返回false,或者它抛出了一个
ConcurrentModificationException
。这不是有效的使用模式。