You are on page 1of 17

Politechnika Śląska

Instytut Informatyki
2002

Laboratorium Architektury Komputerów

JavaSpaces

Opracował:
Adam Świtoński
Laboratorium Architektury Komputerów – JavaSpaces

Spis treści

1 Opis systemu ...................................................................................................................... 2


2 Interfejs programistyczny................................................................................................... 3
2.1 Przestrzeń JavaSpace.................................................................................................. 3
2.2 Wpisy ......................................................................................................................... 4
2.3 Podstawowe operacje ................................................................................................. 5
2.3.1 Zapis do przestrzeni: write ................................................................................. 5
2.3.2 Odczyt z przestrzeni: read, readIfExists............................................................. 6
2.3.3 Pobranie z przestrzeni: take, takeIfExists .......................................................... 6
2.3.4 Powiadomienia: notify ....................................................................................... 7
3 Transakcje .......................................................................................................................... 7
4 Kompilacja i uruchamianie ................................................................................................ 8
4.1 Kompilacja ................................................................................................................. 8
4.2 Uruchamianie ............................................................................................................. 8
4.2.1 Serwer WWW .................................................................................................... 8
4.2.2 Demon aktywacji RMI ....................................................................................... 9
4.2.3 Serwis lookup..................................................................................................... 9
4.2.4 Menadżer transakcji ........................................................................................... 9
4.2.5 Serwis JavaSpace ............................................................................................. 10
4.2.6 Klient JavaSpace .............................................................................................. 11
5 Przykładowe programy .................................................................................................... 11
5.1 Producent-konsument............................................................................................... 11
5.1.1 Klasa wpisu ...................................................................................................... 11
5.1.2 Główna klasa programu ................................................................................... 11
5.2 Nadzorca-wykonawca .............................................................................................. 13
5.2.1 Klasa wpisu z opisem podzadania.................................................................... 14
5.2.2 Klasa wpisu z wynikami podzadania ............................................................... 14
5.2.3 Główna klasa aplikacji ..................................................................................... 14

1
Laboratorium Architektury Komputerów – JavaSpaces

1 Opis systemu
JavaSpaces to system rozproszonych obiektów stworzony przez firmę Sun. Jest on częścią
pakietu JINI, bezpośrednio bazującego na technologiach RMI i Object Serialization, które są
wbudowane w standardowy pakiet JDK*. JavaSpaces to system bliźniaczo podobny do
systemu Linda, reprezentujący model systemu ze współdzieloną pamięcią.

W modelu JavaSpaces zdalni agenci (aplikacje) mogą komunikować się z sobą za


pośrednictwem przestrzeni JavaSpace.

Schemat komunikacji jest następujący:

Rysunek 1

Obiekty przechowywane są w przestrzeni JavaSpace w formie wpisów (ang. entries). Zdalne


aplikacje mogą zapisywać, czytać oraz pobierać wpisy.
Dostęp do wpisów odbywa się za pomocą następującego zestawu funkcji:

• Read:
Czyta wpis pasujący do wzorca

• Write:
Zapisuje wpis do przestrzeni

• Take:
Czyta oraz pobiera wpis pasujący do wzorca

*
Java Development Kit

2
Laboratorium Architektury Komputerów – JavaSpaces

• Notify:
Przez odpowiednią procedurę obsługi zdarzeń, powiadamia o pojawieniu
się w przestrzeni wpisu o danym wzorcu

Kilka pojedynczych operacji może tworzyć transakcję, taką grupę operacji podstawowych,
która musi zostać wykonana w całości lub skutki jej działania muszą zostać wycofane.
Nie ma ograniczeń co do liczby oddzielnych przestrzeni JavaSpaces oraz klientów
w rozproszonej aplikacji. Pojedynczy klient, a nawet pojedyncza transakcja może mieć
dostęp do wielu przestrzeni JavaSpace. Istotną cechą systemu jest brak jakiegokolwiek
porządkowania wykonywanych operacji. Nie można określić jaka będzie kolejność
pobieranych/czytanych wpisów, jeśli klika spośród nich pasuje do wzorca. Podobnie wygląda
sytuacja w przypadku kilku klientów oczekujących na wpis o takim samym wzorcu.

Jak już wcześniej wspomniano, każda przestrzeń JavaSpaces przechowuje dane w postaci tak
zwanych wpisów (ang. entries), które mogą być czytane, zapisywane oraz pobierane
z przestrzeni. Każdy wpis posiada jedno lub więcej pól, które są wykorzystywane w procesie
dopasowywania nadchodzących zgłoszeń. Wszystkie zgłoszenia czytania, pobrania, bądź
powiadamiania o wpisie zawierają wzorzec, do którego dopasowywany jest wpis. Mówimy,
że obiekty wzorca i wpisu są zgodne jeśli są tego samego typu oraz wszystkie pola wzorca nie
mające wartości null muszą być identyczne z odpowiadającymi im polami wpisu. Do badania
identyczności wykorzystywana jest metoda equals klasy java.lang.Object.

2 Interfejs programistyczny

2.1 Przestrzeń JavaSpace

Wszystkie operacje dotyczące przestrzeni wpisów wywoływane są na obiekcie


implementującym interfejs JavaSpace. Obiekt ten stanowi pomost pomiędzy uruchomionym
serwisem JINI, zarządzającym przestrzenią JavaSpace, a aplikacją.
Możliwość korzystania z przestrzeni wpisów musi być poprzedzona wyszukaniem serwisu
JavaSpace. Do tego celu należy:
• Zlokalizować serwis typu ServiceRegistrar, przechowujący informację
o wszystkich uruchomionych serwisach JINI. Dokonujemy tego za pomocą klasy
LookupDiscovery dla serwisów uruchomionych w sieci lokalnej lub
LookupLocator dla serwisów na określonej stacji
• Za pomocą znalezionego serwisu ServiceRegistrar, wyszukać serwis JavaSpace:
public java.lang.Object lookup(ServiceTemplate tmpl)
throws java.rmi.RemoteException
We wzorcu serwisu (ServiceTemplate) podajemy przede wszystkim typ klasy serwisu
(JavaSpace) oraz ewentualnie jego nazwę.

Oczywiście niezbędne jest wcześniejsze uruchomienie serwisów JINI:


• Serwer HTTP*: Serwer WWW jest wykorzystywany do dostarczania bibliotek dla
klientów JINI. Za każdym razem, gdy uruchamiamy aplikację komunikującą się
z przestrzenią JavaSpace, będzie ona potrzebowała klas do komunikacji (np. aby

*
Serwer HTTP nie jest serwisem JINI

3
Laboratorium Architektury Komputerów – JavaSpaces

wysłać wpis). Jako jeden z parametrów wywołania aplikacji JavaSpace oraz


pozostałych serwisów JINI podaje się tak zwany codebase, a więc lokalizację
bibliotek. Uruchomienie serwera WWW nie jest niezbędne, gdyż jako codebase
można podać ścieżkę do lokalnego systemu plików. Jednak z punktu widzenia
elastyczności rozwiązania rozproszonej aplikacji i łatwości jej instalacji,
zdecydowanie lepszym rozwiązaniem jest korzystanie z serwera WWW.
• Demon Aktywacji RMI (ang. RMI Activation Daemon): Demon ten jest
odpowiedzialny za automatyczne uruchamianie serwisów RMI*. Takimi
serwisami są: serwis Lookup, menadżer transakcji oraz serwis JavaSpace. Potrafi
on reaktywować działanie serwisu, który zawiesił się, deaktywować aktualnie
niewykorzystywany serwis oraz ponownie go uruchomić.
• Lookup serwis: Serwis ten rejestruje serwisy JINI dostępne w sieci lokalnej
i jest wykorzystywany przez aplikacje do wyszukiwania serwisów (klasa
ServiceRegistar). Obecnie serwisy można również wyszukiwać za pomocą
rejestrów RMI, jednak ze względu na przyszłe dystrybucje pakietu JINI zalecane
jest korzystanie z serwisu Lookup.
• Menadżer transakcji: Jest on niezbędny podczas korzystania z transakcji. Zarządza
on potwierdzaniem oraz wycofywaniem poszczególnych transakcji.
• Serwis JavaSpace: Serwis zarządzający przestrzenią JavaSpace. Obecnie
zaimplementowane są dwa rodzaje tego serwisu:
o Przejściowy (ang. Transient): Nie zachowuje danych pomiędzy
restartami serwisu
o Trwały (ang. Persistent): Odporny na zawieszanie się i ponowne
uruchamianie serwisu, zarządzany przez demon aktywacji RMI

2.2 Wpisy

Każda przestrzeń JavaSpace zawiera jedynie wpisy, będące obiektami typu Entry, to znaczy
takie, które implementują interfejs Entry (net.jini.core.entry.Entry). Wpisy są zbiorem
referencji do innych obiektów.
Obiekty Entry charakteryzują się następującymi własnościami:
• Muszą być klasami publicznymi
• Wszystkie pola wewnętrzne muszą być publiczną referencją do obiektów (nie
przechowujemy typów elementarnych, ani obiektów private lub protected). Gdy
chcemy przechować zmienne elementarne korzystamy z klas zawijaczy typów:
Integer, Float, Double, Character
• Mogą mieć dowolną liczbę metod i konstruktorów
• Każde pole jest serializowane** oddzielnie, więc referencje do tych samych
obiektów spowodują i tak powstanie różnych kopii tych obiektów
• Muszą mieć bezparametrowy publiczny konstruktor

Niewłaściwy format klasy wpisu nie jest wykrywany podczas kompilacji programu, natomiast
dopiero podczas próby jego serializacji przez mechanizmy przesyłu RMI. Zły format
spowoduje wygenerowanie wyjątku.

*
RMI Remote Method Invocation. System JINI korzysta z RMI jako bazy do zdalnej komunikacji. Jest on
nakładką na RMI.
**
Serializacja jest mechanizmem umożliwiającym zapis/odczyt obiektów do strumienia.

4
Laboratorium Architektury Komputerów – JavaSpaces

W przypadku wpisów zawierających tablice należy korzystać z klas kolekcji (pakiet java.util,
klasy Vector, ArrayList, etc.)

Przykład:

public class Wpis implements Entry {


public String pole1;
public Integer pole2;
public Float pole3;
public Wpis()
{
pole1=null;
pole2=null;
pole3=null;
}
public Wpis(String pole1, Integer pole2, Float pole3)
{
this.pole1=pole1;
this.pole2=pole2;
this.pole3=pole3;
}
public String toString()
{
return pole1;
}
}

2.3 Podstawowe operacje

2.3.1 Zapis do przestrzeni: write


public Lease write(Entry entry, Transaction txn, long lease)
throws TransactionException, java.rmi.RemoteException

Metoda write umieszcza kopię wpisu w przestrzeni JavaSpace. Każda operacja zapisu
powoduje utworzenie nowego wpisu w przestrzeni, nawet w przypadku, gdy wywołano ją
wielokrotnie z referencją do tego samego obiektu Entry.
Każde wywołanie metody write zwraca obiekt typu Lease, przechowujący informację co do
maksymalnego czasu życia wpisu w przestrzeni JavaSpace. Zwykle jest on zgodny
z wartością argumentu wywołania lease, jedynie w skrajnych przypadkach, gdy podany czas
jest zbyt duży może zostać on zredukowany.
Gdy metoda write nie spowoduje wystąpienia wyjątku, wpis zostaje wprowadzony do
przestrzeni. W przypadku, gdy wygenerowany zostanie wyjątek RemoteExcpetion,
oznaczający wystąpienie błądu podczas komunikacji ze zdalnym komputerem, operacja może,
ale nie musi zakończyć się powodzeniem. Pozostałe wyjątki powodują, że wpis nie zostaje
zapisany do przestrzeni JavaSpace.
Zapisanie obiektu może powodować wygenerowanie powiadomień dla zarejestrowanych
obiektów.

5
Laboratorium Architektury Komputerów – JavaSpaces

2.3.2 Odczyt z przestrzeni: read, readIfExists

public Entry read(Entry tmpl, Transaction txn, long timeout)


throws UnusableEntryException, TransactionException,
java.lang.InterruptedException, java.rmi.RemoteException

public Entry readIfExists(Entry tmpl, Transaction txn, long timeout)


throws UnusableEntryException, TransactionException,
java.lang.InterruptedException, java.rmi.RemoteException

Operacje odczytu poszukują w przestrzeni JavaSpace wpisów pasujących do wzorca.


W przypadku, gdy zostanie znaleziony odpowiedni wpis, zwracana jest jego kopia; jeśli nie,
metody read zwracają wartość null. Przekazanie wartości null jako referencji do obiektu
wzorca powoduje pominięcie fazy dopasowania - odczytywany jest wtedy dowolny wpis
znajdujący się w przestrzeni JavaSpace.
Metody read zwracają obiekt klasy Entry, który dalej należy zrzutować na typ klasy wzorca
podanej jako parametr wywołania tej metody.
Różnica pomiędzy read i readIfExist polega na tym, że pierwsza metoda jest blokująca, tj.
zwróci sterowanie dopiero w przypadku, gdy zostanie znaleziony odpowiedni wpis lub
zostanie przekroczony maksymalny czas oczekiwania (parametr timeout), a ReadIfExist
w przypadku, gdy nie ma wpisu pasującego do wzorca od razu zwróci wartość null. Parametr
timeout dla tej metody oznacza maksymalny czas przez jaki należy czekać na zwolnienie
blokad związanych z transakcjami, dla obiektu pasującego do wzorca, który już w momencie
wywołania znajduje się w przestrzeni.

Przykłady :
//korzystamy z wpisu zdefiniowanego powyżej
Wpis wpis=new Wpi(”Opis”,new Integer(20),new Float(1.0));
space.write(wpis,null,defaultLease);

//Wpisy zostaną dopasowane


wpis.pole1=null; //Nie dopasowujemy co do wartości pola pole1
wpis.pole2=new Integer(10); //Pole pole2 musi mieć wartość 10
wpis.pole3=newFloat(1.0); //Pole pole3 musi mieć wartość 1.0
wpis=(Wpis)space.read(wpis,null,defaultLease);

2.3.3 Pobranie z przestrzeni: take, takeIfExists

public Entry take(Entry tmpl, Transaction txn, long timeout)


throws UnusableEntr yException, TransactionException,
java.lang.InterruptedException, java.rmi.RemoteException

public Entry takeIfExists(Entry tmpl, Transaction txn, long timeout)


throws UnusableEntryException, TransactionException,
java.lang.InterruptedException, java.rmi.RemoteException

Operacje pobrania zachowują się dokładnie z tak samo jak operacje odczytu, z tym że
dodatkowo usuwają przeczytane wpisy z przestrzeni JavaSpace. Jeśli zostanie wygenerowany
wyjątek UnusableEntryException, oznaczający, że nie wszystkie pola wpisu zostały
prawidłowo odczytane, wpis pomimo tego zostaje usunięty z przestrzeni.

6
Laboratorium Architektury Komputerów – JavaSpaces

2.3.4 Powiadomienia: notify

public EventRegistration notify(Entry tmpl, Transaction txn,


RemoteEventListener listener, long lease,
java.rmi.MarshalledObject handback)
throws TransactionException,
java.rmi.RemoteException

Metoda notify pozwala śledzić pojawianie się w przestrzeni JavaSpace wpisów o określonym
wzorcu. W momencie, gdy w przestrzeni pojawi szukany obiekt, generowane jest zdarzenie
RemoteEvent i wywoływana jego procedura obsługi listener, podana jako parametr
wywołania metody notify. Argument lease określa czas w milisekundach przez jaki będzie
śledzone pojawienie się wpisu. Parametr handback to obiekt przekazywany do procedury
obsługi zdarzenia jako dodatkowa informacja o źródle rejestracji powiadomienia.

3 Transakcje
Wszystkie operacje na przestrzeni JavaSpace jako jeden z argumentów wywołania pobierają
identyfikator transakcji, będący obiektem klasy Transaction. Wartość null tego argumentu
oznacza powstanie transakcji zawierającej tylko wskazaną operację, w trybie automatycznego
potwierdzenia (ang. autocommit mode).
Transakcje wywierają wpływ na operację w następujący sposób:
• Write: Każdy wpis zapisywany do przestrzeni nie jest widoczny poza transakcją,
aż do momentu zatwierdzenia transakcji. Jeśli wpis zostanie pobrany w ramach tej
samej transakcji, nie będzie on wstawiony do przestrzeni, nawet po zatwierdzeniu
transakcji. W momencie, gdy transakcja jest wycofywana wszystkie jej wpisy
wprowadzone do przestrzeni JavaSpace są usuwane.
• Read: Operacja odczytu może dopasowywać wpisy w ramach własnej transakcji
lub z całej przestrzeni. W ramach własnej transakcji widoczne są również wpisy,
które nie zostały jeszcze zatwierdzone wraz z transakcją.
• Take: Reguły dopasowania są identyczne jak w przypadku operacji Read.
Dodatkowo w przypadku wycofania transakcji pobrane wpisy są ponownie
wstawiane do przestrzeni.
• Notify: Podobnie jak w przypadku operacji odczytu, powiadomienia mogą
dotyczyć wpisów w ramach transakcji lub w całej przestrzeni JavaSpace.
W ramach własnej transakcji powiadomienia będą również generowane dla
wpisów, które nie zostały jeszcze zatwierdzone wraz z transakcją.

Jeśli transakcja jest wycofywana w trakcie, gdy wykonywana jest jakaś operacja w jej
ramach, generowany jest wyjątek TransactionException.

Transakcje tworzymy za pomocą statycznej metody create klasy TransactionFactory:

public static Transaction.Created create(TransactionManager mgr,


long leaseTime)
throws LeaseDeniedException,
java.rmi.RemoteException

7
Laboratorium Architektury Komputerów – JavaSpaces

Pierwszy argument tej metody to menadżer transakcji, który jest serwisem JINI. Musi on być
wcześniej uruchomiony oraz wyszukany analogicznie do serwisu JavaSpace. Drugi argument
to maksymalny czas trwania transakcji podany w milisekundach.

Podstawowe własności transakcji to:


• Niepodzielność (ang. atomicity): Wszystkie operacje zgrupowane w ramach
transakcji są wykonane w komplecie, bądź skutki ich działania są wycofywane.
• Spójność (ang. consistency): Zakończenie transakcji musi gwarantować spójny
stan systemu. Spójność jest odmiennie definiowana dla różnych systemów, toteż
same transakcje nie gwarantują spójności, a są jedynie narzędziem ułatwiającym
jej uzyskanie.
• Izolacja (ang. isolation): Jednocześnie realizowane transakcje nie mają wpływu na
siebie. Zawsze można znaleźć sekwencyjny porządek, który uszereguje kolejno
dokonywane transakcje.
• Trwałość (ang. durability): Wyniki działania transakcji są trwałe niezależnie od
źródła, które ją wywołało.

4 Kompilacja i uruchamianie

4.1 Kompilacja
Kompilacji dokonujemy za pomocą standardowego kompilatora javac pochodzącego z
pakietu JDK. Kompilator taki będzie wymagał jedynie dostępu do odpowiednich bibliotek
JINI:
• jini-core.jar: Interfejsy oraz klasy rdzenia JINI
• jini-ext.jar Dodatkowe Interfejsy oraz klasy JINI (np. interfejs JavaSpace)

Przykładowe wywołanie kompilatora:


javac -d . -classpath
JINI_DIR\lib\jini-core.jar;
JINI_DIR \lib\jini-ext.jar;
ProgramJavaSpace.java

4.2 Uruchamianie

4.2.1 Serwer WWW


Wraz z pakietem JINI dostarczony jest prosty serwer WWW znajdujący się w bibliotece
tools.jar, jednak praktycznie można skorzystać z dowolnego serwera HTTP. Parametrami
wywołania są port, na którym nasłuchiwane są zgłoszenia HTTP oraz katalog główny serwera
WWW.
Przykładowe wywołanie:
java -jar JINI_DIR\lib\tools.jar
-port 8081
-dir JINI_DIR\lib
-verbose

8
Laboratorium Architektury Komputerów – JavaSpaces

4.2.2 Demon aktywacji RMI


Do uruchomienia demona aktywacji RMI służy specjalny program z pakietu JDK rmid.
Opcjonalne parametry wywołania to port, plik policy z uprawnieniami oraz katalog z logu.
Przykładowe wywołanie:
rmid -J-Djava.security.policy=JINI_DIR\example\lookup\policy.all

4.2.3 Serwis lookup


Implementacja serwisu lookup znajduje się w bibliotece reggie.jar. W parametrach wywołania
podajemy następujące dane:
• Zasady zabezpieczeń (ang. policy) dla uruchamianej JVM oraz serwisu. W pliku
o specjalnym formacie (patrz dokumentacja JDK) nadajemy prawa dla
uruchamianego serwisu
• Nazwę katalogu z logiem
• codebase do pliku reggie-dl.jar, w którym znajdują się biblioteki dla aplikacji
klienckich korzystających z serwisu lookup
• Grupę, dla której serwis lookup ma śledzić pojawianie się nowych serwisów

Serwis lookup dalej zostanie przejęty przez demon aktywacji RMI, który będzie sterował jego
działaniem (aktywacją/deaktywacją).

Przykładowe wywołanie:
java -Djava.security.policy=
JINI_DIR\example\lookup\policy.all
-jar JINI_DIR\lib\reggie.jar
http://localhost:8081/reggie-dl.jar
JINI_DIR\example\lookup\policy.all
JINI_DIR\tmp\reggie_log
public

4.2.4 Menadżer transakcji


Implementacja menadżera transakcji znajduje się w bibliotece mahalo.jar.
W parametrach wywołania podajemy następujące informacje:
• Zasady zabezpieczeń dla uruchamianej JVM oraz serwisu
• Nazwa menadżera transakcji
• Nazwę katalogu z logiem
• codebase do pliku mahalo-dl.jar, w którym znajdują się biblioteki dla aplikacji
klienckich korzystających z menadżera transakcji

Przykładowe wywołanie:
java -Djava.security.policy=
JINI_DIR\example\lookup\policy.all
-jar JINI_DIR\lib\mahalo.jar
http://localhost:8081/mahalo-dl.jar
JINI_DIR\example\lookup\policy.all
JINI_DIR\tmp\trans_log
public

9
Laboratorium Architektury Komputerów – JavaSpaces

4.2.5 Serwis JavaSpace

4.2.5.1 Transient Space


Implementacja tego serwisu znajduje się w bibliotece transient-outrigger.jar. W parametrach
wywołania przekazujemy następujące informacje:
• Zasady zabezpieczeń dla uruchamianej JVM
• Nazwę przestrzeni JavaSpace
• codebase do pliku outrigger-dl.jar, w którym znajdują się biblioteki dla aplikacji
klienckich korzystających z przestrzeni JavaSpace
• Grupę serwisu lookup

Przykładowe wywołanie:
java -Djava.security.policy=
JINI_DIR\example\books\policy.all
-Djava.rmi.server.codebase=
http://localhost:8081/outrigger-dl.jar
-Dcom.sun.jini.outrigger.spaceName=JavaSpaces
-jar JINI_DIR\lib\transient-outrigger.jar
public

4.2.5.2 PersistentSpace
Implementacja tego serwisu znajduje się w bibliotece outrigger.jar. W parametrach
wywołania przekazujemy następujące informacje:
• Zasady zabezpieczeń dla uruchamianej JVM i serwisu.
• codebase do pliku outrigger-dl.jar, w którym znajdują się biblioteki dla aplikacji
klienckich korzystających z przestrzeni JavaSpace
• Nazwę przestrzeni JavaSpace
• Nazwę katalogu z logiem
• Grupę serwisu lookup

Przykładowe wywołanie:
java -Djava.security.policy=
JINI_DIR\example\books\policy.all
-jar JINI_DIR\lib\outrigger.jar
http://localhost:8081/outrigger-dl.jar
-Dcom.sun.jini.outrigger.spaceName=JavaSpaces
JINI_DIR\example\books\policy.all
JINI_DIR\tmp\js_log
Public

10
Laboratorium Architektury Komputerów – JavaSpaces

4.2.6 Klient JavaSpace

Aplikację kliencką również wywołujemy za pomocą interpretera* java z pakietu JDK. Należy
jedynie podać do ścieżki przeszukiwania classpath biblioteki JINI: jini-core.jar i jini-ext.jar oraz
określić zasady zabezpieczeń dla uruchamianej aplikacji w pliku policy.

Przykładowe wywołanie:
java -Djava.security.policy=JINI_DIR\example\lookup\policy.all
-classpath JINI_DIR\lib\jini-core.jar;JINI_DIR\jini1_2_1_001\lib\jini-ext.jar;.;
ProgramJavaSpace arg1 arg2

5 Przykładowe programy

5.1 Producent-konsument

Pierwszym przykładem jaki rozważymy będzie rozproszona aplikacja producenta-


konsumenta. Zakładamy, że istnieje tylko po jednej instancji procesów producenta i
konsumenta oraz w nieskończonej pętli produkują/konsumują one wpisy. Dodatkowo
wymagamy, aby wpisy były konsumowane w tej samej kolejności w jakiej są produkowane.

5.1.1 Klasa wpisu


Wpis będzie zawierał dwa pola, pierwsze będzie obiektem klasy String będące opisem, drugie
obiektem Integer zawierającym unikalny identyfikator wpisu.

public class Data implements Entry {


public String desc;
public Integer id;
}

5.1.2 Główna klasa programu


public class ProducentKonsument {

int defaultLease=100000;
int id=1; //Identyfikator aktualnie produkowanego/konsumowanego wpisu

//Konstruktor
public ProducentKonsument()
{
//Wyszukanie serisu typu lookup
Space.discoverLookupServices(null);
}

//Metoda implementująca działanie producenta


public void producer()
{
try {

• Dla obecnych maszyn wirtualnych Java nie jest to już interpreter w dosłownym znaczeniu tego słowa.

11
Laboratorium Architektury Komputerów – JavaSpaces

//Pobranie referencji do przestrzeni JavaSpace


JavaSpace space=Space.getSpace(spaceName);

while(true)
{
//Wyprodukowanie wpisu
Data data=produce();
//Zapisanie wpisu do przestrzeni JavaSpace
space.write(data,null,defaultLease);
}

} catch(Exception ex) //Przechwycenie wyjątków mogących się pojawić podczas


{
System.out.println(ex); //wypisanie komunikatu o wyjątku
}
}

//Wyprodukowanie wpisu
private Data produce()
{
Data data=new Data();
data.desc="Porcja";
data.id=new Integer(id++);
return Data;
}

//Metoda implementująca proces konsumenta


public void consumer()
{
try {
//Pobranie referencji do przestrzeni JavaSpace
JavaSpace space=Space.getSpace(spaceName);

//Wzorzec wpisu do pobrania


Data data=new Data();
int id=1;
while(true)
{
//Pole desc nie będzie dopasowywane co do wartości
data.desc=null;

//Pole id będzie dopasowywane również co do wartości


data.id=new Integer(id++);

//Pobranie wpisu
data=(Data)space.take(data,null,defaultLease);

//Skonsumowanie wpisu
cosnume(data);

}
} catch(Exception ex)
{
System.out.println(ex);
}
}

//Metoda konsumująca wpis

12
Laboratorium Architektury Komputerów – JavaSpaces

private void consume(Data data)


{
System.out.println("Konsumowana "+data.desc+" "+data.id.toString());
}

//Główna funkcja aplikacji


public static void main(String[] args)
{
ProducentKonsumentt pk=new ProducentKonsument();
if(args[0].equalsIgnoreCase("producent"))
pk.producer();
else if(args[0].equalsIgnoreCase("Konsument"))
pk.consumer();

}
}

5.2 Nadzorca-wykonawca

Drugi program jaki zostanie zaprezentowany będzie to rozproszona aplikacja działająca


w oparciu o architekturę nadzorca-wykonawca, wyznaczająca liczbę Π na podstawie pola
powierzchni ćwierćkola.

1 2 4 ⋅ Pćwierćkola
Pćwierćkola = ⋅ ∏⋅r ⇒ ∏= 2
4 r
Do wyznaczenia pola powierzchni ćwierćkola zastosujemy metodę losowych strzałów Monte
Carlo.

Znajdujemy obszar ograniczający nasze ćwierćkole* - jest to kwadrat o długości boku r


i środku symetrii w punkcie (r/2;r/2). Dokonujemy losowych strzałów do wnętrza kwadratu,
sprawdzając następnie czy trafiliśmy pod krzywą ćwierćkola czy nie.
Pole powierzchni ćwierćkola będzie równe:

liczba _ strzalów _ trafionych


Pćwierćkola = ⋅ Pkwadratu
liczba _ wszystkich _ strzalów

Sprawdzenie czy trafiliśmy pod krzywą będzie jednoznaczne ze spełnieniem nierówności:

• Bierzemy prawe górne ćwierćkole koła o promieniu r i środku w punkcie (0;0)

13
Laboratorium Architektury Komputerów – JavaSpaces

2 2
y≤ r −x
gdzie (x,y) to współrzędne wylosowanego punktu.

Nasze zadanie z punktu widzenia aplikacji rozproszonej to wykonanie n strzałów i zliczenie


liczby strzałów trafionych. Pojedynczym podzadaniem dla procesu wykonawcy będzie
wykonanie n1 strzałów. Wartości n i n1 to parametry wejściowe programu.

5.2.1 Klasa wpisu z opisem podzadania

public class Task implements Entry {

public Integer parameter; //liczba strzałów do wykonania w ramach zadania

5.2.2 Klasa wpisu z wynikami podzadania

public class Result implements Entry {

public Integer hits; // liczba trafionych strzałów


public Integer misses; //liczba nietrafionych strzałów

5.2.3 Główna klasa aplikacji


//Implementacja procesu nadzorcy
public class PIDistApp {

int defaultLease=100000;
//Konstruktor
public PDistApp()
{
//Wyszukanie serisu typu lookup
Space.discoverLookupServices(null);
}

public void supervisor(int numOfShots,int shotPerTask)


{
//pobranie referencji do obiektu przestrzeni JavaSpace
JavaSpace space=Space.getSpace(“spaceName”);
try {
Task task=new Task(); //wpis z opisem podzadania
//Rozesłanie podzadań
for(int shot=0;shot<=numOfShots;shot+=shotPerTask)
{

14
Laboratorium Architektury Komputerów – JavaSpaces

task.parameter=new Integer((shot+shotPerTask)<=numOfShots
?(shotPerTask):(numOfShots-shot));
space.write(task,null,defaultLease);
}
int totalHits=0;
int totalMisses=0;
Result result=new Result();

//zbieranie wyników podzadań


for(int shot=0;shot<=numOfShots;shot+=shotPerTask) {
result.hits=null;
result.misses=null;
result=(Result)space.take(result,null,defaultLease);
totalHits+=result.hits.intValue();
totalMisses+=result.misses.intValue();
System.out.println("Wyniki częściowe: PI:"+
(4*(double)totalHits/(double)(totalHits+totalMisses)));
}
System.out.println("Wyniki końcowe: PI:"+
(4*(double)totalHits/(double)(totalHits+totalMisses)));
task.parameter=null;
//Wysłanie pigułki trującej, informującej procesy wykonawców o zakończeniu obliczeń
space.write(task,null,defaultLease);
} catch(Exception ex) //Przechwycenie ewentualnych wyjątków
{
System.out.println(ex);
}

//Implementacja procesu wykonawcy


public void worker()
{

try {
//pobranie referencji do przestrzeni JavaSpace
JavaSpace space=Space.getSpace(“spaceName”);

//pobranie referencji do obiektu menadżera transakcji


TransactionManager txnManager=Space.getTransactionManager();

while(true)
{
Task task=new Task(); //wpis z opisem podzadania
task.parameter=null;

//Stworzenie nowej transakcji


Transaction transaction=TransactionFactory.create(txnManager,
defaultLease).transaction;

//Pobranie zadamoa
task=(Task)space.take(task,transaction,defaultLease);

//Jeśli pigułka trująca


if(task.parameter==null) {
transaction.abort();
return;
}

15
Laboratorium Architektury Komputerów – JavaSpaces

//wykonanie podzadania
Result result=work(task.parameter);

Zwrócenie rezultatów
space.write(result,transaction,defaultLease);

/Zatwierdzenie transakcji
transaction.commit();
}

} catch(Exception ex)
{
System.out.println(ex);
}
}

//Implementacja wykonania podzadania


public Result work(Integer param)
{
int numOfShots=param.intValue(); //Liczba strzałów w ramach podzadania
int hits=0; //strzały trafione
int misses=0; //strzały nietrafione
Random random=new Random();

for(int i=0;i<numOfShots;i++)
{
// r=1
double x=random.nextDouble();
double y=random.nextDouble();
if((x*x+y*y)<=1)
hits++;
else
misses++;

Result result=new Result(); //Obiekt wyników


result.hits=new Integer(hits);
result.misses=new Integer(misses);

return result;
}

//Główna metoda aplikacji


public static void main(String[] args)
{
PIDistApp app=new PIDistApp ();
if(args[0].equalsIgnoreCase("Nadzorca"))
app.supervisor(Integer.parseInt(arg[1])), Integer.parseInt(args[2])));
else if(args[0].equalsIgnoreCase("Wykonawca"))
app.worker();

}
}

16

You might also like