Параллелизм Java на практике — листинг 5.11

#java #concurrency

#java #параллелизм

Вопрос:

В книге JCiP, в листинге 5.11, этот код будет ждать вечно, если какой-либо из Thread t будет прерван (потому что startGate.await() может выбросить InterruptedException ), поэтому защелка конечного входа никогда не будет выпущена?

 public class TestHarness { 
public long timeTasks(int nThreads, final Runnable task) 
        throws InterruptedException { 
    final CountDownLatch startGate = new CountDownLatch(1); 
    final CountDownLatch endGate = new CountDownLatch(nThreads); 

    for (int i = 0; i < nThreads; i  ) { 
        Thread t = new Thread() { 
            public void run() { 
                try { 
                    startGate.await(); 
                    try { 
                        task.run(); 
                    } finally { 
                        endGate.countDown(); 
                    } 
                } catch (InterruptedException ignored) { } 
            } 
        }; 
        t.start(); 
    } 

    long start = System.nanoTime(); 
    startGate.countDown(); 
    endGate.await(); 
    long end = System.nanoTime(); 
    return end-start; 
}} 
  

Комментарии:

1. sthupahsmaht, независимо от того, попробует ли он это. Это правильный вопрос, учитывая, что он публикуется в широко используемой и высоко цитируемой книге.

2. да, я пробовал, и он ждет. Все еще не могу поверить, что эта ошибка есть в книге, надеясь, что кто-нибудь объяснит, что я ошибаюсь

3. Действительно похоже на недостаток. Его нет в списке ошибок для книги: javaconcurrencyinpractice.com/errata.html Если вы действительно считаете, что произошла ошибка, вы можете отправить ее туда.

Ответ №1:

Вы не ошибаетесь. Код фактически зависнет. Имейте в виду, что многие из их примеров кода написаны для того, чтобы дать читателю представление о том, что должен функционально выполнять фрагмент кода. Они не предназначены для того, чтобы разработчики использовали свой код «из коробки» без собственного тестирования.

Например, кто-то спрашивал о создании самозаполняющегося кэша. Кто-то указал на раздел Memoizer в JCiP, за которым последовал Тим Пайерлс с:

Класс Memoizer, представленный в этом разделе, предназначен только для иллюстрации метода. Ему не хватает ряда полезных функций, и он далеко не готов к работе.

Используйте MapMaker везде, где у вас могло возникнуть желание использовать или адаптировать Memoizer.

http://old.nabble.com/How-to-implement-a-self-populating-memoizer-cache—td30121001.html