Lab13

background image

Programowanie obiektowe /Java/
Laboratorium nr 13

Uwaga !!! Wyniki uruchomionych programów mogą zależeć od sprzętu (ilość procesorów, rdzeni itp.),

systemu operacyjnego i jego obciążenia, ilości wątków w programie (zmienna SIZE), itp.

1

Wątki

Interfejs Runnable

1

:

public void run() – metoda, która ma się wykonywać współbieżnie.

W celu uruchomienia nowego wątku należy w wybranej klasie zaimplementować interfejs Runnable. Na-

stępnie jako parametr konstruktora klasy T hread należy przekazać obiekt klasy implementującej ten interfejs,
a następnie dla utworzonego wątku należy wywołać metodę start().

1

package

pl.kielce.tu.lab13;

2
3

import

java.util.concurrent.TimeUnit;

4
5

public class

TestRunnable

implements

Runnable {

6

private int

t;

7
8

public

TestRunnable(

int

t) {

9

this

.t = t;

10

}

11
12

public void

run() {

13

for

(

int

i = 0; i < 20; i++) {

14

System.out.println(

this

);

15

try

{

16

TimeUnit.MILLISECONDS.sleep(t);

17

// lub Thread.sleep(t);

18

}

catch

(InterruptedException e) {

19

e.printStackTrace();

20

}

21

}

22

}

23
24

public static void

main(String[] args) {

25

Thread t1 =

new

Thread(

new

TestRunnable(1000));

26

t1.start();

27

Thread t2 =

new

Thread(

new

TestRunnable(10000));

28

t2.start();

29

}

30

}

Przykład 1: src/pl/kielce/tu/lab13/TestRunnable.java {link}

Klasa T hread

W celu stworzenia nowego wątku w klasie dziedziczącej po T hread należy przesłonić metodę run(), a następnie
dla wątku wywołać metodę start().

1

package

pl.kielce.tu.lab13;

2
3

import

java.util.concurrent.TimeUnit;

4
5

public class

TestThread

extends

Thread {

6

private int

t;

7

1

Thinking in Java, Bruce Eckel, Wydanie IV, Helion, 2006

1

background image

8

public

TestThread(

int

t) {

9

this

.t = t;

10

}

11
12

@Override

13

public void

run() {

14

for

(

int

i = 0; i < 20; i++) {

15

System.out.println(

this

);

16

try

{

17

TimeUnit.MILLISECONDS.sleep(t);

18

}

catch

(InterruptedException e) {

19

e.printStackTrace();

20

}

21

}

22

}

23
24

public static void

main(String[] args) {

25

TestThread t1 =

new

TestThread(1000);

26

t1.start();

27

TestThread t2 =

new

TestThread(10000);

28

t2.start();

29

}

30

}

Przykład 2: src/pl/kielce/tu/lab13/TestThread.java {link}

Wybrane metody klasy Thread:

- public void run() – metoda, która ma się wykonywać współbieżnie,

- public void start() – rozpoczyna wykonywanie nowego wątku,

- public void join() throws InterruptedException – oczekuje na zakończenie się wątku,

- public void interrupt() – przerywa działanie wątku,

- public final boolean isAlive() – sprawdza czy wątek się zakończył,

- public final boolean isDaemon() – sprawdza czy wątek jest wątkiem działającym w tle.

Proszę porównać działanie poniższego programu:

- z komentarzami,

- z jednym (dowolnym) komentarzem,

- bez komentarzy?

1

package

pl.kielce.tu.lab13;

2
3

public class

TestThreadDaemon

extends

Thread {

4
5

public static void

main(String[] args) {

6

TestThread t1 =

new

TestThread(1000);

7

// t1.setDaemon(true);

8

t1.start();

9

TestThread t2 =

new

TestThread(10000);

10

// t2.setDaemon(true);

11

t2.start();

12

}

13

}

Przykład 3: src/pl/kielce/tu/lab13/TestThreadDaemon.java {link}

2

background image

- public final boolean isInterrupted() – sprawdza czy działanie wątku zostało przerwane,

- public static void sleep(long millis) throws InterruptedException – usypia aktualny wątek na podany

czas,

- public final void yield() – wstrzymuje wykonanie aktualnego wątku umożliwiając wykonywanie się innych

wątków,

- public final void setPriority(int newPriority) – ustawia priorytet wątku,

- public final int getPriority() – pobiera priorytet wątku.

„Unikaj modyfikacji priorytetów wątków

2

, gdyż zwiększają zależność od platformy i stwarzają problemy

z żywotnością.”

W Javie 1.5 dodano pakiet java.util.concurrent. Od Javy 1.5 zalecaną metodą uruchamiania wątków jest

metoda wykorzystująca klasy z tego pakietu (Executors).

1

package

pl.kielce.tu.lab13;

2
3

import

java.util.concurrent.ExecutorService;

4

import

java.util.concurrent.Executors;

5

import

java.util.concurrent.TimeUnit;

6
7

public class

TestCachedThreadPool

implements

Runnable {

8
9

private int

t;

10
11

public

TestCachedThreadPool(

int

t) {

12

this

.t = t;

13

}

14
15

public void

run() {

16

for

(

int

i = 0; i < 20; i++) {

17

System.out.println(

this

);

18

try

{

19

TimeUnit.MILLISECONDS.sleep(t);

20

}

catch

(InterruptedException e) {

21

e.printStackTrace();

22

}

23

}

24

}

25
26

public static void

main(String[] args) {

27

Thread t1 =

new

Thread(

new

TestCachedThreadPool(1000));

28

Thread t2 =

new

Thread(

new

TestCachedThreadPool(10000));

29

ExecutorService e = Executors.newCachedThreadPool();

30

e.execute(t1);

31

e.execute(t2);

32

e.shutdown();

33

}

34

}

Przykład 4: src/pl/kielce/tu/lab13/TestCachedThreadPool.java {link}

1

package

pl.kielce.tu.lab13;

2
3

import

java.util.concurrent.ExecutorService;

4

import

java.util.concurrent.Executors;

5

import

java.util.concurrent.TimeUnit;

6

2

Goetz B., Peierls T., Bloch J., Bowbeer J., Holmes D., Lea D., Java Współbieżność dla praktyków, Helion 2007

3

background image

7

public class

TestFixedThreadPool

implements

Runnable {

8
9

private int

t;

10
11

public

TestFixedThreadPool(

int

t) {

12

this

.t = t;

13

}

14
15

public void

run() {

16

for

(

int

i = 0; i < 20; i++) {

17

System.out.println(

this

);

18

try

{

19

TimeUnit.MILLISECONDS.sleep(t);

20

}

catch

(InterruptedException e) {

21

e.printStackTrace();

22

}

23

}

24

}

25
26

public static void

main(String[] args) {

27

Thread t1 =

new

Thread(

new

TestFixedThreadPool(1000));

28

Thread t2 =

new

Thread(

new

TestFixedThreadPool(10000));

29

ExecutorService e = Executors.newCachedThreadPool();

30

e.execute(t1);

31

e.execute(t2);

32

e.shutdown();

33

}

34

}

Przykład 5: src/pl/kielce/tu/lab13/TestFixedThreadPool.java {link}

2

Uruchamianie programów

1

package

pl.kielce.tu.lab13;

2
3

import

java.io.BufferedReader;

4

import

java.io.IOException;

5

import

java.io.InputStreamReader;

6
7

public class

TestProcess {

8

public static void

main(String[] args)

throws

IOException,

9

InterruptedException {

10

Runtime runtime = Runtime.getRuntime();

11

Process process = runtime.exec(

"ipconfig /all"

);

12

BufferedReader input =

new

BufferedReader(

new

InputStreamReader(

13

process.getInputStream()));

14

String s =

null

;

15

while

((s = input.readLine()) !=

null

) {

16

if

(s.length() > 0) {

17

s = s.replace(

’.’

,

’_’

);

18

s = s.replace(

’:’

,

’_’

);

19

s = s.replace(

’ ’

,

’_’

);

20

System.out.println(s);

21

}

22

}

23

input.close();

24

process.waitFor();

25

Process process2 = runtime.exec(

"notepad"

);

26

process2.waitFor();

4

background image

27

System.out.println(

"end"

);

28

}

29

}

Przykład 6: src/pl/kielce/tu/lab13/TestProcess.java {link}

Od wersji Javy 1.5 metoda ProcessBulider.start() jest zalecaną metodą tworzenia procesów.

1

package

pl.kielce.tu.lab13;

2
3

import

java.io.BufferedReader;

4

import

java.io.File;

5

import

java.io.IOException;

6

import

java.io.InputStreamReader;

7
8

public class

TestProcessBuilder {

9

public static void

main(String[] args)

throws

IOException,

10

InterruptedException {

11
12

ProcessBuilder processBuilder =

new

ProcessBuilder(

13

"C:\\WINDOWS\\system32\\ipconfig"

,

"/all"

);

14

processBuilder.directory(

new

File(

"C:\\"

));

15

Process process = processBuilder.start();

16
17

BufferedReader input =

new

BufferedReader(

new

InputStreamReader(

18

process.getInputStream()));

19

String s =

null

;

20

while

((s = input.readLine()) !=

null

) {

21

if

(s.length() > 0) {

22

s = s.replace(

’.’

,

’_’

);

23

s = s.replace(

’:’

,

’_’

);

24

s = s.replace(

’ ’

,

’_’

);

25

System.out.println(s);

26

}

27

}

28

input.close();

29

process.waitFor();

30
31

ProcessBuilder processBuilder2 =

new

ProcessBuilder(

32

"C:\\WINDOWS\\notepad"

);

33

Process process2 = processBuilder2.start();

34

process2.waitFor();

35

System.out.println(

"end"

);

36

}

37

}

Przykład 7: src/pl/kielce/tu/lab13/TestProcessBuilder.java {link}

3

Współdzielenie zasobów

Uwaga!!! Aplikacja może działać w nieskończoność. Czy aplikacja kiedykolwiek się zakończy? Czy jest moż-

liwe, aby value.i kiedykolwiek przyjęło wartości -1 lub 2 (działanie programu może być zależne od parametrów
podanych na początku instrukcji)?

1

package

pl.kielce.tu.lab13;

2
3

import

java.util.concurrent.TimeUnit;

4
5

public class

TestNoSynchronization

extends

Thread {

6

final private static int

SIZE = 2;

5

background image

7

static

MyObject value =

new

MyObject();

8
9

@Override

10

public void

run() {

11

while

(

true

) {

12

switch

(value.i) {

13

case

0:

14

value.i++;

// 0 + 1 = 1 ???

15

break

;

16

case

1:

17

value.i--;

// 1 - 1 = 0 ???

18

break

;

19

default

:

20

System.err.println(

"ERROR "

+ value.i);

21

System.exit(1);

22

}

23

try

{

24

TimeUnit.MICROSECONDS.sleep(10);

25

}

catch

(InterruptedException e) {

26

e.printStackTrace();

27

}

28

}

29

}

30
31

public static void

main(String[] args) {

32

TestNoSynchronization[] t =

new

TestNoSynchronization[SIZE];

33

for

(

int

i = 0; i < SIZE; i++) {

34

t[i] =

new

TestNoSynchronization();

35

t[i].start();

36

}

37

}

38
39

static class

MyObject {

40

int

i = 0;

41

}

42

}

Przykład 8: src/pl/kielce/tu/lab13/TestNoSynchronization.java {link}

4

Synchronizowana metoda

Metoda synchronizowana może być wykonywana w tym samym czasie tylko przez jeden wątek np.

synchronized public int method(){

...

}

Uwaga!!! Aplikacja może działać w nieskończoność. Jaka jest różnica w działaniu programu po usunięciu

komentarza (zaobserwowanie różnicy może być zależne od parametrów podanych na początku instrukcji
laboratoryjnej) ?

1

package

pl.kielce.tu.lab13;

2
3

import

java.util.concurrent.TimeUnit;

4
5

public class

TestSynchronizedMethod

extends

Thread {

6

final private static int

SIZE = 2;

7
8

static

MyObject value =

new

MyObject();

9

10

@Override

6

background image

11

public void

run() {

12

while

(

true

) {

13

switch

(value.method()) {

14

case

0:

15

case

1:

16

break

;

17

default

:

18

System.err.println(

"ERROR "

);

19

System.exit(1);

20

}

21

try

{

22

TimeUnit.MICROSECONDS.sleep(10);

23

}

catch

(InterruptedException e) {

24

e.printStackTrace();

25

}

26

}

27

}

28
29

public static void

main(String[] args) {

30
31

TestSynchronizedMethod[] t =

new

TestSynchronizedMethod[SIZE];

32

for

(

int

i = 0; i < SIZE; i++) {

33

t[i] =

new

TestSynchronizedMethod();

34

t[i].start();

35

}

36

}

37
38

static class

MyObject {

39
40

private int

i = 0;

41
42

/* synchronized */

public int

method() {

43

if

(i == 0)

44

return

++i;

45

if

(i == 1)

46

return

--i;

47

return

i;

48

}

49

}

50

}

Przykład 9: src/pl/kielce/tu/lab13/TestSynchronizedMethod.java {link}

5

Blok synchronizowany

W celu wykonania bloku synchronizowanego wymagane jest uzyskanie blokady obiekt synchronizującego.

W danym momencie tylko jeden wątek może uzyskać taką blokadę.

synchronized (obiektSynchronizujący) {

...

}

Uwaga!!! Aplikacja może działać w nieskończoność. Jaka jest różnica w działaniu programu po usunięciu

komentarza (zaobserwowanie różnicy może być zależne od parametrów podanych na początku instrukcji
laboratoryjnej) ?

1

package

pl.kielce.tu.lab13;

2
3

import

java.util.concurrent.TimeUnit;

4
5

public class

TestSynchronizedBlock

extends

Thread {

7

background image

6

final private static int

SIZE = 2;

7
8

static

MyObject value =

new

MyObject();

9

10

@Override

11

public void

run() {

12

while

(

true

) {

13

// synchronized (value)

14

{

15

switch

(value.i) {

16

case

0:

17

value.i++;

18

break

;

19

case

1:

20

value.i--;

21

break

;

22

default

:

23

System.err.println(

"ERROR "

+ value.i);

24

System.exit(1);

25

}

26

try

{

27

TimeUnit.MICROSECONDS.sleep(10);

28

}

catch

(InterruptedException e) {

29

e.printStackTrace();

30

}

31

}

32

}

33

}

34
35

public static void

main(String[] args) {

36

TestSynchronizedBlock[] t =

new

TestSynchronizedBlock[SIZE];

37

for

(

int

i = 0; i < SIZE; i++) {

38

t[i] =

new

TestSynchronizedBlock();

39

t[i].start();

40

}

41

}

42
43

static class

MyObject {

44

int

i = 0;

45

}

46

}

Przykład 10: src/pl/kielce/tu/lab13/TestSynchronizedBlock.java {link}

6

Monitor

Klasa Object zawiera monitor pozwalający synchronizować dostęp. Wybrane metody klasy Object:

- public final void wait() throws InterruptedException – wątek zostaje zatrzymany, aż do wywołania me-

tody notif y() lub notif yAll(), istnieją także przesłonięte wersje tej metody ograniczające maksymalny
czas czekania,

- public final void notify(), public final void notifyAll() – budzi wątek (lub wątki) czekające na monitorze

obiektu.

Metody te mogą być tylko wywoływane w synchronizowanej metodzie lub synchronizowanym bloku!

1

package

pl.kielce.tu.lab13;

2
3

import

java.util.Random;

4

import

java.util.concurrent.TimeUnit;

8

background image

5
6

class

Bufor {

7

int

value;

8

}

9

10

class

Reader

extends

Thread {

11

Bufor b;

12
13

Reader(Bufor b) {

14

this

.b = b;

15

}

16
17

@Override

18

public void

run() {

19

try

{

20

for

(

int

i = 0; i < 10; i++) {

21

synchronized

(b) {

22

// Poczekaj na powiadomienie od Piszącego

23

System.err.println(

">"

);

24

b.wait();

25

System.err.println(

">> Czytający "

+ b.value);

26

// Powiadom czekającego Piszącego

27

b.notify();

28

System.err.println(

">>>"

);

29

}

30

}

31

}

catch

(InterruptedException e) {

32

e.printStackTrace();

33

System.exit(1);

34

}

35

}

36

}

37
38

class

Writer

extends

Thread {

39
40

Bufor b;

41
42

Writer(Bufor b) {

43

this

.b = b;

44

}

45
46

Random r =

new

Random();

47
48

@Override

49

public void

run() {

50

try

{

51

for

(

int

i = 0; i < 10; i++) {

52

synchronized

(b) {

53

int

t = r.nextInt(1000);

54

b.value = t;

55

TimeUnit.MICROSECONDS.sleep(t);

56

System.err.println(

"< Piszący "

+ b.value);

57

// Powiadom czekającego Czytającego

58

b.notify();

59

System.err.println(

"<<"

);

60

// Poczekaj na powiadomienie od Czytającego

61

b.wait();

62

System.err.println(

"<<<"

);

63

}

64

}

65

}

catch

(InterruptedException e) {

66

e.printStackTrace();

9

background image

67

System.exit(1);

68

}

69
70

}

71

}

72
73

public class

TestMonitor

extends

Thread {

74
75

public static void

main(String[] args) {

76

Bufor b =

new

Bufor();

77

Writer p =

new

Writer(b);

78

Reader c =

new

Reader(b);

79

c.start();

80

p.start();

81

}

82

}

Przykład 11: src/pl/kielce/tu/lab13/TestMonitor.java {link}

7

Kolekcje synchronizowane

public static <T> List<T> synchronizedList(List<T> list)
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)
public static <T> Set<T> synchronizedSet(Set<T> s)
public static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m)

8

Timer

Uruchamianie zadań o określonej porze i / lub z określonym odstępem czasu.

1

package

pl.kielce.tu.lab13;

2
3

import

java.util.Date;

4

import

java.util.Timer;

5

import

java.util.TimerTask;

6
7

public class

TestTimer

extends

Thread {

8
9

public static void

main(String[] args) {

10

MyTask task =

new

MyTask();

11

Timer timer =

new

Timer();

12

timer.schedule(task,

new

Date(), 1000);

13

}

14
15

static class

MyTask

extends

TimerTask {

16

@Override

17

public void

run() {

18

System.err.print(

"#"

);

19

}

20

}

21

}

Przykład 12: src/pl/kielce/tu/lab13/TestTimer.java {link}

„Klasa ScheduledThreadPoolExecutor

2

poprawnie radzi ze źle zachowującymi się zadaniami, więc nie ma

powodów, by stosować klasę Timer w aplikacjach Javy 5.0 lub nowszych.”

1

package

pl.kielce.tu.lab13;

2
3

import

java.util.concurrent.ScheduledThreadPoolExecutor;

10

background image

4

import

java.util.concurrent.TimeUnit;

5
6

public class

TestScheduledThreadPoolExecutor

extends

Thread {

7

public static void

main(String[] args)

throws

InterruptedException {

8

ScheduledThreadPoolExecutor executor =

new

ScheduledThreadPoolExecutor(1);

9

executor.schedule(

new

MyTask(), 1, TimeUnit.SECONDS);

10

executor.shutdown();

11

executor.awaitTermination(1, TimeUnit.DAYS);

12

}

13
14

static class

MyTask

implements

Runnable {

15

@Override

16

public void

run() {

17

System.err.print(

"#"

);

18

}

19

}

20

}

Przykład 13: src/pl/kielce/tu/lab13/TestScheduledThreadPoolExecutor.java {link}

9

Java 1.5 a współbieżność

Dodatkowe elementy w Java 1.5 związane ze współbieżnością można znaleźć w pakietach:

- java.util.concurrent,

- java.util.concurrent.atomic,

- java.util.concurrent.locks.

Należą do nich między innymi:

- klasy atomowe np. AtomicLong, AtomicInteger, itp.,

- kolekcje bezpieczne wątkowo: ConcurrentHashM ap < K, V >, ConcurrentSkipListM ap < K, V >,

ConcurrentSkipListSet < E >

, ConcurrentLinkedQueue < E >,

- kolekcje kopiujące przy zapisie: CopyOnW riteArrayList, CopyOnW riteArraySet,

- kolejki blokujące: BlockingQueue < E >, BlockingDeque < E >,

- synchronizatory: CountDownLatch, CyclicBarrier, Exchanger, Semaphore, SynchronousQueue.

10

Przykładowa treść laboratorium

1. Proszę stworzyć aplikację graficzną zawierającą dwa komponenty graficzne. Zawartość obydwu kompo-

nentów powinna zmieniać się niezależnie co określony przedział czasu. Zadanie należy wykonać przy
użyciu T hread, Runnable oraz T imer (lub ScheduledT hreadP oolExecutor).

2. Proszę stworzyć aplikację, w której zostanie wykorzystany współbieżny dostęp do tego samego obiektu

przez kilka wątków przy użyciu synchronizowanych metod, synchronizowanych bloków oraz monitora
klasy Object. Wątki powinny zostać uruchomione poprzez Executors.newCachedT hreadP ool() lub
Executors.newCachedT hreadP ool

().

3. Proszę stworzyć aplikację, która uruchomi dowolny, wykonywalny program znajdujący się na dysku

(np. P aint.exe dla systemu operacyjnego W idnows).

11


Document Outline


Wyszukiwarka

Podobne podstrony:
i2 lab13
lab13 5 3
Lab lab13
lab13, lab6x
lab13
Lab13
lab13 SWBlab13
UKLADY, LAB13 P, POLITECHNIKA WROC˙AWSKA
LAB13 , Fizyka laborki, Fizyka (laby i inne), FizLab, fizlab, 013 LE~1
lab13 lab6x
lab13 6 1
Inf Lab13
Kopia lab13
lab13 Bazy Danych4 id 750409 Nieznany
Lab13 RapidPrototyping
Inf Lab13
cwiczenie13, Elektrotechnika AGH, Semestr II letni 2012-2013, Fizyka II - Laboratorium, laborki, lab

więcej podobnych podstron