Java как центр архипелага | страница 15
ется обект класса SomethingToъun, а, значит, последовательность
выполняемых действий потока будет определяться методом run()
этого класса. Вызов метода start() в строке 7 ставит поток в
очередь готовых для выполнения.
4.1.6.2. Средства синхронизации потоков
Как и во всякой многопроцессной или многопотоковой среде, в
Java существует проблема синхронизации доступа к разделяемым
ресурсам. Примером такого ресурса является буфер в задаче "про-
изводитель/потребитель".
Для опытных программистов отметим, что модель синхронизации,
принятая в языке Java, опирается на концепцию монитора, предло-
женную в 70-е годы Бринк-Хансеном.
В Java-программах можно выделять критические интервалы, которые
обозначаются ключевым словом synchronized. Если критическим ин-
тервалом является метод, спецификатор synchronized помещается в
его (метода) заголовок. Для превращения произвольной инструкции
(обычно это блок) в критический интервал служит конструкция
synchronized (выражение) инструкция;
где результатом выражения должен быть об®ект или массив.
Выполнение критического интервала начинается только после полу-
чения потоком монопольного доступа к соответствующему об®екту.
До наступления этого момента поток блокируется.
Вызов wait() внутри критического интервала приводит к тому, что
текущий поток уступает монопольное право на критический интер-
вал и приостанавливается до тех пор, пока из какого-либо друго-
го потока не будет сделан вызов notify() или notifyAll(). Хоро-
шей иллюстрацией использования средств синхронизации потоков
является упоминавшаяся выше программа Марка Тиллотсона.
class my_buffer
{
Object [] vec = new Object [8] ;
int ip = 0 ;
int ep = 0 ;
synchronized void insert (Object item)
{
do
{
if (ip-ep < 8)
{ vec [(ip++) & 7] = item ;
if (ip-ep == 1) notify () ; // Уведомить, если буфер был пуст
return ;
}
try wait () ; catch (InterruptedException e) ;
} while (true) ;
}
synchronized Object extract ()
{
do
{
if (ip > ep)
{ Object result = vec [(ep++) & 7] ;
if (ip-ep == 7) notify(); // Уведомить, если буфер был полон
return result ;
}
try wait () ; catch (InterruptedException e) ;
} while (true) ;
}
}
class my_producer extends Thread
{
int items_to_do ;
my_buffer the_buffer ;