Почему родительский поток не выполняется после дочернего потока? - PullRequest
0 голосов
/ 23 марта 2019

Я написал некоторый код для прохождения потокобезопасного 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

Почему родительский поток не выполняется после этого? Любые выводы будут полезны и будут оценены.

1 Ответ

2 голосов
/ 23 марта 2019

Первая проблема с вашим кодом заключается в том, что вы создаете итератор для основного потока, прежде чем какие-либо записи будут добавлены в 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 (например, put, putAll, get, size и т. Д.) Синхронизированы, итераторы, которые вы можете создать , вообще не синхронизируются , за исключением remove метод.

Особенно итерации по Hashtable не мешают другим потокам итерировать по нему, как вы, вероятно, ожидаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...