Nie wiem czy Bóg istnieje, ale byłoby z korzyścią dla Jego reputacji, gdyby nie istniał" - Renard

start(); } // funkcja synchronizujca public synchronized void incXY(int x, int y) { p.x = (x+1) % 100; p.y = (y+1) % 100; } public void run() { Graphics gDC = getGraphics(); while(true) { int x, y; synchronized(this) { x = Math.abs(p.x); y = Math.abs(p.y); } gDC.drawLine(0, 0, x, y); incXY(x, y); } } } Instrukcja synchronizujca Instrukcja synchronizujca ma posta synchronized(obj) block w ktrej obj jest odnonikiem do synchronizatora, a block jest blokiem. Jeli w chwili podjcia wykonywania instrukcji synchronizujcej stwierdzi si, e obiekt identyfikowany przez obj nie jest przydzielony obcemu wtkowi, to przydzieli si go biecemu wtkowi na czas wykonywania bloku instrukcji synchronizujcej albo do chwili, gdy w tym bloku zostanie wywoana metoda wait. W przeciwnym razie, wtek zostaje zatrzymany. Uwaga: Opracowanie nagwka tej samej instrukcji synchronizujcej przez rne wtki moe dotyczy rnych obiektw identyfikowanych przez obj. W tym rzadkim przypadku nie nastpi zatrzymanie wtku. Jeli wtkowi przydzielono ten sam obiekt wielokrotnie synchronized(lock) { // ... synchronized(lock) { // ... } // ... } to zwolnienie obiektu nastpi dopiero wwczas, gdy zakoczy si wykonywanie najszerszej instrukcji synchronizujcej albo gdy w ciele dowolnej z nich zostanie wywoana metoda wait. Jeli zakoczenie wykonywania instrukcji synchronizujcej spowoduje zwolnienie synchronizatora, to jeden z wtkw zatrzymanych na tym obiekcie zostanie oywiony, tj. dopuszczony do kontynuowania zawierajcej go instrukcji albo funkcji synchronizujcej. Nastpujcy aplet, pokazany na ekranie Instrukcjesynchronizujce, ilustruje zastosowanie synchronizacji na skutek ktrej nie uda si spowodowa, aby wyprowadzenie napisu Action nastpio midzy napisami Beforesleep i Aftersleep. Ekran Instrukcje synchronizujce ### syncins.gif =============================================== import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class Master extends Applet implements Runnable { private Integer lock = new Integer(0); private Button button = new Button("Action"); private TextArea area = new TextArea(); private Thread thread; public void init() { setLayout(new BorderLayout()); add(button, BorderLayout.WEST); add(area, BorderLayout.CENTER); button.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { show("Action"); } } ); thread = new Thread(this); thread.start(); } public void run() { while(true) try { synchronized(lock) { show("\nBefore sleep"); thread.sleep(3000); show("After sleep"); } } catch(InterruptedException e) { } } public void show(String string) { synchronized(lock) { area.append(string + "\n"); } } } Funkcje synchronizujce Funkcj synchronizujc jest funkcja zadeklarowana ze specyfikatorem synchronized. Jeli jest metod, to wykonuje si j tak, jakby jej ciao zawarto w instrukcji zaczynajcej si od synchronized(this) a jeli jest funkcj statyczn klasy Name, to wykonuje si j tak, jakby jej ciao zawarto w instrukcji zaczynajcej si od synchronized(Name.class) w ktrej Name.class jest nazw unikalnego synchronizatora klasy Name. Ma to taki skutek, e na czas wykonywania funkcji synchronizujcej, zostanie zatrzymany kady inny wtek, ktry podejmie prb wykonania dowolnej funkcji synchronizujcej jej klasy, posugujcej si tym samym synchronizatorem. Nastpujcy aplet, pokazany na ekranie Funkcjesynchronizujce, ilustruje zastosowanie synchronizacji na skutek ktrej nie uda si spowodowa, aby napis Action zosta wyprowadzony midzy napisami Beforesleep i Aftersleep. Ekran Funkcje synchronizujce ### syncfun.gif =============================================== import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class Master extends Applet implements Runnable { private Button button = new Button("Action"); private TextArea area = new TextArea(); private Thread thread; public void init() { setLayout(new BorderLayout()); add("West", button); add("Center", area); button.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { show("Action"); } } ); thread = new Thread(this); thread.start(); } public synchronized void show(String string) { area.append(string + "\n"); } public synchronized void sleep() { try { show("\nBefore sleep"); thread.sleep(3000); show("After sleep"); } catch(InterruptedException e) { } } public void run() { while(true) sleep(); } } Metody wait Wywoanie metody wait ma posta obj.wait() obj.wait(ms) obj.wait(ms, ns) // ms + 0.001*ns w ktrej obj jest odnonikiem do obiektu, a ms i ns s liczbami okrelajcymi czas w milisekundach. Wykonanie metody wait moe wystpi tylko w bloku takiej instrukcji synchronizujcej, w ktrej do synchronizacji uyto obiektu identyfikowanego przez obj. W przeciwnym razie, z miejsca wykonania metody, zostanie wysany wyjtek klasy IllegalMonitorStateException. Wtek wywoujcy bezparametrow metod wait jest wstrzymywany na czas nieokrelony. Jeli wywoa jedn z pozostaych metod, to zostanie wstrzymany na czas nie duszy ni okrelony za pomoc argumentw. A zatem otoczenie wywoania metody wait przybiera zazwyczaj posta synchronized(lock) { // ... try { lock.wait(); } catch(IllegalMonitorStateException e) { // ... } catch(InterruptedException e) { // ... } } Jeli wywoania metody wait nie poprzedzono nazw obiektu, a wywoanie znajduje si w ciele metody, to domylnie przyjmuje si, e chodzi o wywoanie na rzecz obiektu identyfikowanego przez this. A zatem poprawna jest m.in