Здравствуйте, bolshik, Вы писали:
B>1. Скажите пожалуйста, после прочтения аннотации у меня сложилось впечатление, что книга ставит своей целью просто рассказать о классах из java.util.concurrent и его подпакетов. Так ли это?
По сути, можно ответить словами авторов из предисловия к книге (я их привел уже):
Java 5.0 is a huge step forward for the development of concurrent applications in Java, providing new higher-level components and additional low-level mechanisms that make it easier for novices and experts alike to build concurrent applications. The authors are primary members of the JCP Expert Group that created these facilities; in addition to describing their behavior and features, we present the underlying design patterns and anticipated usage scenarios that motivated their inclusion in the platform libraries.
Они действительно делают хороший упор на java.util.concurrent и классы коллекций, но, с другой стороны — ведь это и есть основные "кирпичики" для построения многопоточности в яве (высокоуровневой многопоточности).
В последних главах (начиная с 9 примерно) повествование отходит прямо уж от явного использования java.util.concurrent и обсуждаются более продвинутые вопросы и способы их оптимальной и корректной реализации. Чтение реально полезное и интересное. Из простых вещей, там обсуждавшихся: вы знаете, что в многопоточном коде при использовании несколькими потоками одного экземпляра следующего класса (пример не из книги, но суть оттуда) после вызова метода setter одним потоком, а метода test — другим, test может вернуть true? (речь шла о возможности переупорядочивания операций)
class Test
{
private int a;
private boolean b;
public Test() {a = 0; b = false;}
public void setter() { a = 1; b = true;}
public boolean test() {
if ((a == 0) && (b)) return true;
return false;
}
}
B>2. Как вы считаете, на какой уровень расчитана эта книга? Вопрос возник потому, что в приведенном примере баг. Если представить ситуацию, когда вычисления объемны и длительны по времени, то возможно следующее -- клиент вызывает compute(), начинаются расчеты. После этого N других клиентов делают запрос на вычисление по тому же аргументу. Если расчеты длятся недопустимо долго, то данные уже могут стать не нужны первому клиенту. Он отменяет свой запрос. При этом мы с определенной вероятностью попадаем в бесконечный цикл.
Да, знаю

Вот абзац из текста книги:
Caching a Future instead of a value creates the possibility of cache pollution: if a computation is cancelled or fails, future attempts to compute the result will also indicate cancellation or failure. To avoid this, Memoizer removes the Future from the cache if it detects that the computation was cancelled; it might also be desirable to remove the Future upon detecting a RuntimeException if the computation might succeed on a future attempt. Memoizer also does not address cache expiration, but this could be accomplished by using a subclass of FutureTask that associates an expiration time with each result and periodically scanning the cache for expired entries. (Similarly, it does not address cache eviction, where old entries are removed to make room for new ones so that the cache does not consume too much memory.)
Жирным я выделил то, на что Вы указали в коде. Однако, если убрать такие требования, то класс является полностью потокобезопасным, что уже не мало.
Данный пример был приведен в конце 5ой главы. Что касается того, как нужно работать с задачами, у которых есть лимит времени выполнения (6 глава) или как нужно прерывать задачи (7 глава) — так это было дальше по книге
На мой взгляд, книжка рассчитана на людей, понимающих что есть многопоточность, и, наверное, пробовавших нарисовать что-то своё многопоточное.
Первая часть книги описывает то, как нужно писать потокобезопасный код ВНУТРИ потока: как прятать данные, как их лочить и т.д. Вторая часть описывает то, как управлять потоками. Третья и четвертая — всё по-немногу, но на более продвинутом уровне.
Да, кстати говоря, в книге упоминаются и классы, добавленные в Java 1.6.