![](/user_photo/2706_HbeT2.jpg)
GrandM-Patterns_in_Java
.pdfFuture - 53
Некоторый объект будет инициировать создание объекта Future. Он будет пе·
редавать объект Future другим объектам, которые будут получать доступ к это· му объекту через интерфейс, ничего не зная о классе объекта Future или О еГ< участии в шаблоне Future. Когда шаблоны Future и Рroху объединяются подоб·
ным образом и вычисление является синхронным, результатом будет шаблOJ
Virtual Рroху.
З а пус к с и н х ро н н о го в ы ч и сл е н и я
Если объект Future инкапсулирует синхронное вычисление, он должен имеп возможность запустить вычисление при первом вызове его метода getResult Чтобы запустить вычисление, объект Future должен иметь возможность полу·
чить все необходимое для вычисления параметров. Поэтому, если класс Future
инкапсулирует синхронное вычисление, конструктор этого класса должен бу дет получить соответствующие параметры с целью задания значений этих пара метров для выполнения вычисления.
Ра нд е в у
Реализация класса Future, работающего с асинхронным вычислением, вклю чает взаимодействие потока, который вызывает метод getResul t этого класса с целью ожидания завершения вычисления. Существует название для некото рого механизма синхронизации нескольких потоков с целью ожидания Toro момента, пока один или некотор- ые из них не достигнут определенной точки. Название этого механизма рандеву.
Класс j ava . lang . Thread содержит метод под названием j oin, который обес печивает подходящий способ реализации рандеву. Метод j oi n объекта Thread
не возвращается до тех пор, пока поток не «умрет». Если поток выполняет
асинхронное вычисление, связанное с объектом Future, а затем завершается, то объект Future может вызвать метод j oin этого потока для взаимодействия с ним.
Поток не обязательно должен «умирать» по окончании вычисления. Он может
сделать еще что-то. Он может управляться пулом потоков (щаблон Thread Pool, описанный в книге [Grand2001 ]), который может многократно использовать этот поток для других вычислений. Чтобы реализовать рандеву таким спосо бом, который не знает, что будет делать поток после окончания асинхронного вычисления, нужно использовать методы wai t и not ifyAll . Листинг класса
AsynchronousFuture в разделе «Пример кода» служит примером применения
такого способа.
И с кл ю ч е н и я
Если вычисление, связанное с объектом Future, генерирует исключение, нуж но, чтобы оно могло быть получено методом, вызвавшим метод getResul t объекта Future. Если вычисление выполняется синхронно, то любые генери руемые им исключения, естественно, могут быть получены вне рамок метода getResul t объекта Future.
540 • Глава 9. Шаблоны проектирования дпя конкурирующих операций
Если вычисление является асинхронным и генерируется исключение, то есте
ственный ход событий таков, что исключение будет генерироваться в текущем
активном потоке. Чтобы такое исключение могло быть получено методом,
вызвавшим метод getResul t объекта Future, нужно перехватить это исключе
ние и задать ссылку на него в одной из переменных экземпляра объекта
Future. Далее можно реализовать метод getResul t так, чтобы этот метод ге
нерировал исключение, на которое ссьшается переменная экземпляра (если
она не равна nul l).
СЛЕДСТВИЯ
©Классы, использующие вычисление, освобождаются от какой бы то ни
было ответственности за поддержку параллельности.
©Если вычисление асинхронное, за все детали синхронизации отвечает класс
Future.
ПРИМЕНЕНИЕ В JAVA API
Класс j ava . awt . MediaTracker может служить примером шаблона Future в Java API. Класс MediaTracker инкапсулирует процесс асинхронной загрузки данных изображения в объект ImageProducer, связанный с объектом Image. Он исполняет и роль Requester, и роль Future.
Класс MediaTracker не инкапсулирует результат загрузки данных изображе ния. Он просто инкапсулирует процесс загрузки данных. Объект ImagePro ducer выполняет роль объекта Resul t.
ПРИМЕР КОдА
Пример кода для этого шаблона основан на проектировании классов, предна значенных для считывания текущей информации о погоде, рассматривавшейся
в разделе «Контекст» . Первым представлен класс WeatherRequester, который исполняет роль запрашивающей стороны.
public class WeatherRequester {
/* *
* Объект, который выполняет реаль ную работу
*по считыванию информации о погоде .
*/
WeatherFetchIF fetcher ;
public WeatherRequester (WeatherFetchIF fetcher) { this . fetcher = fetcher;
} // constructor (WeatherFetchIF)
![](/html/2706/346/html_MxkKzTLKJz.Ja4Q/htmlconvd-LkZgZ6533x1.jpg)
![](/html/2706/346/html_MxkKzTLKJz.Ja4Q/htmlconvd-LkZgZ6534x1.jpg)
542 • Глава 9. Шаблоны проектирования АЛЯ конкурирующих операций
public WeatherFuture (WeatherFetchIF fetcher ,
|
|
|
Coordinate location) |
|
|
|
|
this . fetcher = fetcher; |
|
|
|
||
|
this . location = location; |
|
|
|||
|
futureSupport = new AsynchronousFuture ( ) ; |
|||||
|
new Runner ( ) . start ( ) ; |
|
|
|
||
|
11 |
cons t ructor (WeatherFetchI F, |
Coordinate ) |
|||
1 * * |
|
|
|
|
|
|
|
* |
Возвращает true, если запрошенная информация |
||||
|
*1 |
|
|
|
||
|
* |
о погоде была прочитана . |
|
|
||
public boolean check ( ) { |
|
|
|
|||
} * |
11 |
checkResult ( ) |
|
|
|
|
|
return futureSupport . checkResult ( ) ; |
|
||||
1 * *Возвращает объе т Result |
для |
этого |
объе та Future . |
|||
* |
1 |
Если он еще не получен , |
ждет, |
по а |
он не будет получен . |
|
|
|
public synchronized WeatherIF waitForWeather ( ) throws
Exception {
11return (WeatherIF) futureSupport . qetResult( ) ;
1**
getResu l t ( )
*
* Этот закрытьм класс представляет общую логи у
* 1для асинхронного считывания те ущей информации о погоде .
private class Runner extends Тhread {
|
public void run ( ) { |
|
|
|
try { |
= fetcher . fetchWeather (location) ; |
|
|
|
WeatherIF info |
|
|
|
futureSupport . setResult (info) ; |
|
|
|
catch (Exception е) { |
|
|
|
11 try |
|
|
11 |
futureSupport . setException (e) ; |
|
11 |
run ( ) |
|
|
11 class runner |
|
||
|
|
||
|
class |
Weathe rFuture |
|
![](/html/2706/346/html_MxkKzTLKJz.Ja4Q/htmlconvd-LkZgZ6535x1.jpg)
Future •
Если информация о погоде прочитана, она инкапсулируется в экзем
класса, который реализует интерфейс под названием Weathe r I F. Логика вления асинхронным вычислением содержится в многократно использ: классе под названием AsynchronousFuture.
public class AsynchronousFuture private Object result i
private boolean resultIsSet;
private Exception problem;
/ * *
* Возвращает true , если результат был получен .
* /
public boolean checkResult ( )
return resultIsSet ;
} |
/ / |
checkResult ( ) |
|
|
/ * * |
|
|
|
|
'* |
Возвращает объект Result для этого объекта Future . |
|||
'* |
Если он еще не получен, ждет, |
пока |
он не будет получен . |
|
'* / |
|
|
|
|
public synchronized Object getResult ( ) |
throws Exception { |
|||
|
while ( ! resultIsSet) |
|
|
|
|
|
wait ( ) ; |
|
|
|
} |
/ / whi le |
|
|
|
if |
(problem!=null) |
|
|
|
} |
/ / if problem |
|
|
|
|
throw problemi |
|
|
|
return result i |
|
|
|
|
/ / |
getResult ( ) |
|
|
/ |
|
|
|
|
'* '* |
|
|
|
|
'* |
Обращаемся к этому методу для задания результата |
|||
'* |
вычисления . |
|
|
|
.. |
Этот метод должен вызываться |
только |
один раз . |
|
' * / |
|
|
|
|
public synchronized void setResult (Object result) |
||||
|
if |
(resultIsSet) { |
|
|
|
|
String msg = "Result iз already set" ; |
||
|
|
throw new IllеgаlstаtеЕхсерtiоn (mзg) i |
![](/html/2706/346/html_MxkKzTLKJz.Ja4Q/htmlconvd-LkZgZ6536x1.jpg)
544 • Глава 9. Шаблоны проектирования АЛЯ конкурирующих операций
this . result = result;
resultIsSet = true ;
notifyAll ( ) ;
// setResul t (Obj ec t )
/ * *
* |
Если асинхронное вычисление , связанное с этим объектом, |
* |
генерирует исключение , передаем исключение этому методу, |
* и исключение будет снова сгенерировано методом getResult .
*/
public synchronized void setException (Exception е) ( problem = е ;
resultIsSet = true ; notifyAll ( ) ;
//setExcept ion (Exception )
//class AsynchronousFuture
ШАБЛОНЫ ПРОЕКТИРОВАНИЯ, СВЯЗАННЫЕ С ШАБЛОНОМ FUTURE
Asynchronous Processing. Шаблон Asynchronous Processing позволяет делать вы числение асинхронным. Он часто используется вместе с шаблоном Future.
Observer. Использование шаблона ObseIVer представляет собой альтернативный вариант технологии реализации опроса в объекте Future для определения, было
ли завершено связанное с ним асинхронное вычисление.
Proxy. Шаблон Future может объединяться с шаблоном Ргоху с тем, чтобы объ
ект Future являлся также заместителем для объекта, который выполняет основ ное вычисление.
Virtual Proxy. Если шаблон Future объединяется с шаблоном Ргоху и вычисле
ние синхронное, то получается шаблон Virtual Proxy.
Active Object. Шаблон Active Object, представленный в [SSRBOO), описывает
способ объединения шаблона Future с шаблоном Asynchronous Processing.
СПИСОК ЛИТЕРАТУРЫ
[App1eton97]wwwBrad App1eton. «Patterns and Software: Essential Concepts and Termi nology.» .enteract.comjbradapp/docs/patterns-intro.html.
[ASU86] Alfred У. Лhо, Ravi Seti, and JefТery О. Ullman. Compilers, Principles, Tech niques and Too/s. Reading, Mass.: Addison-Wesley, 1986.
[Bentley86] Jon Louis Bentley. Programming Pearls. New York: АСМ, 1986.
[BMRSS96] Frank Buschmann, Regine Meunier, Hans Rohnert,J:Peter Sommerlad and Michael Stal. Pattern-Oriented So/tware& Architecture, Volume А System о/ Ра! tems. Chichester, England: John Wiley Sons, 1996.
[GoF95] Erich ааmmа, Richard Helm, Ralph Johnson, and John Vlissides. Desig, Patterns: Elements о/ ReusabIe Object-Oгiented Software. Reading, Mass.: Addi son-Wesley, 1995.
[Grand99] Grand Mark. Patterns2. in Java: А Catalog о/ ReusabIe Design Pattems Illus trated with UML, Volume Wiley, 1999.
[Grand2001 ] Grand Mark. Java Enterprise Design Pattems: Pattems in Java, Volume j
Wiley, 2001.
[Larman98] Craig Larman. App/ying UML and Patterns. Upper Saddle River, N.J Prentice НаН PTR, 1998.
[Lea97] Doug Lea. Concurrent Programming in Java. Reading, Mass.: Addison-Wesle) 1997.
[LLO] ] Timothy С. Lethbridge and Robert Laganiere. Object-Oriented So/tware Engi neeгing: Practica/ Software Deve/opment Using UML and Java. New York: МсGгаw-НiI1 2001.
[RhieI2000]wwwDirk Rhiel. Fundamenta/ Class Pattems in Java. UnpubIished manuscrip (in 2000). .riehle.org/papers/2000/plop-2000-class-pattems.html.
[Ritchie84] О. Ritchie. «А Stream Input-Output System,» АТ&Т Ве// Labs TechnicG Jouma/, vol. 63, рр. 3 1 1-324. October 1984.
[SSRBOO] Douglas Schmidt, Micheal Stal, Hans2. Rohnert, and Frank Buschmann
Pattern Oriented So/tware Architecture, Volume Chichester, England: John Wiley Sons, 2000. www
[Woolf97] ВоЬЬу Woolf. «The Null Object Pattern.» .ksccary.com/nullobj.htm
![](/html/2706/346/html_MxkKzTLKJz.Ja4Q/htmlconvd-LkZgZ6540x1.jpg)