• Nie Znaleziono Wyników

Systemy Rozproszone - Ćwiczenie 3

N/A
N/A
Protected

Academic year: 2021

Share "Systemy Rozproszone - Ćwiczenie 3"

Copied!
7
0
0

Pełen tekst

(1)

Systemy Rozproszone - Ćwiczenie 3

1 Współbieżny dostęp do obiektu

Poniżej znajduje się bardzo prosta klasa - licznik, mający 2 metody: inc() zwiększający licznik o 1 i getValue() zwracający aktualną wartość licznika.

W ramach rozgrzewki napisz program, który będzie zwiększać licznik przez 2 sekundy, a po 2 sekundach wypisze wartość licznika. Do tego celu można np.

wykorzytać System.currentTimeMillis().

/∗ p l i k S i m p l e C o u n t e r . j a v a ∗/

public c l a s s S i m p l e C o u n t e r { private i n t v a l u e ;

public S i m p l e C o u n t e r ( ) { v a l u e = 0 ;

}

public void i n c ( ) { v a l u e ++;

}

public i n t g e t V a l u e ( ) { return v a l u e ;

} }

Następnie stworzymy program, który utworzy 3 wątki i 1 obiekt Simple- Counter. W konstruktorze każdemu wątkowi przekazana zostanje referencja do obiektu SimpleCounter. Każdy proces zwiększa licznik 10 razy. Zastanów się co ostatecznie wypisze program na wyjściu, a następnie sprawdź to uruchomiając program.

public c l a s s SyncDemo extends Thread { S i m p l e C o u n t e r s o ;

public SyncDemo ( S i m p l e C o u n t e r o b j ) { s o = o b j ;

}

(2)

public void run ( ) {

f o r ( i n t i =0; i <10; i ++) { s o . i n c ( ) ;

} }

public s t a t i c void main ( S t r i n g a r g s [ ] ) {

S i m p l e C o u n t e r c o u n t e r = new S i m p l e C o u n t e r ( ) ; SyncDemo t h r e a d 1 = new SyncDemo ( c o u n t e r ) ; SyncDemo t h r e a d 2 = new SyncDemo ( c o u n t e r ) ; SyncDemo t h r e a d 3 = new SyncDemo ( c o u n t e r ) ; t h r e a d 1 . s t a r t ( ) ;

t h r e a d 2 . s t a r t ( ) ; t h r e a d 3 . s t a r t ( ) ; try {

t h r e a d 1 . j o i n ( ) ; t h r e a d 2 . j o i n ( ) ; t h r e a d 3 . j o i n ( ) ; }

catch ( I n t e r r u p t e d E x c e p t i o n e ) { System . o u t . p r i n t l n ( " I n t e r r u p t e d " ) ; }

System . ou t . p r i n t l n ( c o u n t e r . g e t V a l u e ( ) ) ; }

}

Zwiększ ilość iteracji pętli w metodzie run() do 100, 1000, 100000. Przetestuj działanie programu dla różnej liczby wątków (od 1 do 10). Czy wyniki są zgodne z oczekiwaniami? Co mogło pójść nie tak? Zastanów się nad tym wspólnie z kolegą siedzącym obok Ciebie. Podpowiedź znajduje się na następnej stronie.

(3)

Co poszło nie tak?

Wszystkie 3 procesy wykonywały równolegle metodę inc(). Linia value++ to tak naprawdę 3 instrukcje atomowe:

• skopiowanie zmiennej do rejestru: LD R,value

• zwiększ rejestr: INC R

• skopiowanie rejestru do zmiennej: LD value,R

Zastanów się jaki może wystąpić przeplot tych operacji atomowych podczas wy- konywania metody inc() przez 2 procesy. Odpowiedź znajduje się na następnej stronie.

(4)

Niekorzystny przeplot operacji

/∗

∗ p r z y k l a d na z w i e k s z a n i e o 1 p r z e z 2 p r o c e s y ( P0 , P1 ) r o w n o c z e s n i e

P0 : LD R, x z a l a d u j x do r e j e s t r u

P0 : INC R z w i e k s z r e j e s t r

P1 : LD R, x P1 : INC R

P0 : ST R, x z a p i s z x do r e j e s t r u

P1 : ST R, x

∗/

Problem równoczesnego dostępu do metody można rozwiązać poprzez użycie słowa synchronized w deklaracji metody. Poczytaj nt. synchronized i spróbuj naprawić licznik.

2 Sekcje krytyczne wewnątrz metody

Przykład:

public c l a s s AdvancedCounter { private i n t v a l u e 1 = 0 ; private i n t v a l u e 2 = 0 ;

private O b j e c t l o c k 1 = new O b j e c t ( ) ; private O b j e c t l o c k 2 = new O b j e c t ( ) ;

public void i n c 1 ( ) { synchronized ( l o c k 1 ) {

v a l u e 1 ++;

} }

public void i n c 2 ( ) { synchronized ( l o c k 2 ) {

v a l u e 2 ++;

} }

public i n t g e t 1 ( ) { return v a l u e 1 ; }

public i n t g e t 2 ( ) { return v a l u e 2 ;

(5)

} }

3 Sekcje krytyczne - piaskownica

Poeksperymentuj z poniższym programem używając słowa kluczowego synchronized zarówno dla metod jak i bloków kodu.

c l a s s Shared {

public void f o o ( S t r i n g threadName , long t i m e ) { System . ou t . p r i n t l n ( threadName +

" ␣ i s ␣ r u n n i n g ␣ f o o ( ) ␣ f o r ␣ "+t i m e+" ␣ms , ␣ c t : " + System . c u r r e n t T i m e M i l l i s ( ) ) ;

long t = System . c u r r e n t T i m e M i l l i s ( ) ;

while ( System . c u r r e n t T i m e M i l l i s () − t < t i m e ) { Math . a t a n ( System . c u r r e n t T i m e M i l l i s ( ) ) ; }

}

public void bar ( S t r i n g threadName , long t i m e ) { System . ou t . p r i n t l n ( threadName +

" ␣ i s ␣ r u n n i n g ␣ bar ( ) ␣ f o r ␣ "+t i m e+" ␣ms , ␣ c t : " + System . c u r r e n t T i m e M i l l i s ( ) ) ;

long t = System . c u r r e n t T i m e M i l l i s ( ) ;

while ( System . c u r r e n t T i m e M i l l i s () − t < t i m e ) { Math . a t a n ( System . c u r r e n t T i m e M i l l i s ( ) ) ; }

} }

c l a s s ThreadA extends Thread { Shared s h a r e d ;

ThreadA ( Shared i n s t a n c e ) { t h i s . s h a r e d = i n s t a n c e ; }

public void run ( ) {

s h a r e d . f o o ( "A" , 5 0 0 0 ) ; s h a r e d . ba r ( "A" , 1 0 0 0 ) ;

System . ou t . p r i n t l n ( "A␣ i s ␣ done " ) ; }

}

c l a s s ThreadB extends Thread { Shared s h a r e d ;

(6)

ThreadB ( Shared i n s t a n c e ) { t h i s . s h a r e d = i n s t a n c e ; }

public void run ( ) {

s h a r e d . f o o ( "B" , 1 0 0 0 ) ; s h a r e d . ba r ( "B" , 2 0 0 0 ) ;

System . ou t . p r i n t l n ( "B␣ i s ␣ done " ) ; }

}

public c l a s s J a v a A p p l i c a t i o n 1 { /∗ ∗

∗ @param a r g s t h e command l i n e arguments

∗/

public s t a t i c void main ( S t r i n g [ ] a r g s ) { // TODO c o d e a p p l i c a t i o n l o g i c h e r e Shared s h a r e d = new Shared ( ) ;

ThreadA t h 1 = new ThreadA ( s h a r e d ) ; ThreadB t h2 = new ThreadB ( s h a r e d ) ; long t = System . c u r r e n t T i m e M i l l i s ( ) ; t h 1 . s t a r t ( ) ;

t h 2 . s t a r t ( ) ; try {

t h 1 . j o i n ( ) ; t h 2 . j o i n ( ) ; }

catch ( I n t e r r u p t e d E x c e p t i o n e ) { System . o u t . p r i n t l n ( e ) ;

}

System . ou t . p r i n t l n ( " done ␣ i n ␣ " + ( System . c u r r e n t T i m e M i l l i s ( ) − t ) + " ␣ms" ) ; }

}

4 Zakleszczenie

Dlaczego dochodzi do zakleszczenia?

public c l a s s DeadlockDemo1 { s t a t i c c l a s s F r i e n d {

private f i n a l S t r i n g name ;

(7)

public F r i e n d ( S t r i n g name ) { t h i s . name = name ;

}

public S t r i n g getName ( ) { return t h i s . name ;

}

public synchronized void bow ( F r i e n d bower ) { System . o u t . f o r m a t ( "%s : ␣%s ␣ has ␣bowed␣ t o ␣me!%n" ,

t h i s . name , bower . getName ( ) ) ; bower . bowBack ( t h i s ) ;

}

public synchronized void bowBack ( F r i e n d bower ) { System . o u t . f o r m a t ( "%s : ␣%s ␣ has ␣bowed␣ back ␣ t o ␣me!%n" ,

t h i s . name , bower . getName ( ) ) ; }

}

public s t a t i c void main ( S t r i n g [ ] a r g s ) {

f i n a l F r i e n d a l p h o n s e = new F r i e n d ( " Alphonse " ) ; f i n a l F r i e n d g a s t o n = new F r i e n d ( " Gaston " ) ; new Thread (new Runnable ( ) {

public void run ( ) { a l p h o n s e . bow ( g a s t o n ) ; }

} ) . s t a r t ( ) ;

new Thread (new Runnable ( ) { public void run ( ) {

g a s t o n . bow ( a l p h o n s e ) ; }

} ) . s t a r t ( ) ; }

}

5 Zadania

Na razie nic....

Cytaty

Powiązane dokumenty

krótka pisana wierszem lub prozą bohaterowie to najczęściej zwierzęta (ale też przedmioty, rośliny,

Wydaje się, że to jest właśnie granica, wzdłuż której przede wszystkim tworzyła się Europa Wschodnia, lub raczej wschodnia wersja „europejskości”: jest to

korzystać!), na 1 pozycji jest zapis: Epodręczniki.pl, proszę kliknąć wyświetli się pierwszy kafelek: kształcenie ogólne, kliknąć, wyjdzie zapis: szkoła.. ponadpodstawowa:

Niech h(n) oznacza liczbę sposobów połaczenia tych punktów w pary tak, że otrzymane odcinki nie przecinają się.. Na ile sposobów możemy to zrobić, jeśli w

Dziel się dobrymi praktykami i

Wraz z szybkim rozwojem technologii infor- matycznych (między innymi zwiększeniem szybkości sieci, wzrostem wydajności kom- puterów) pojawiła się potrzeba opracowania

W przypadku ciał skończonych charakterystyka ciała jest liczbą pierwszą, a ciało rozsze- rzone zachowują charakterystykę ciała prostego, nad którym zostało

W wyniku sta- rzenia chronologicznego (starzenie wewnątrzpo- chodne, naturalne, zachodzące wraz z wiekiem), jak i starzenia zewnątrzpochodnego (starzenie przy- spieszone