Procesy i wątki Proces posiada samodzielne środowisko wykonawcze. Proces posiada własny zestaw podstawowych zasobów w czasie wykonywania; W szczególności, każdy proces ma własną przestrzeń pamięci. W uproszczeniu proces można utożsamiać z działającą aplikacją lub programem. Większość implementacji VM w Javie działa jako samodzielny proces. W ramach jednego procesu może działać wiele wątków. Wątki działające w obrębie jednego procesu współdzielą zasoby, w szczególności pamięć. Język obsługuje programowanie wielowątkowe.
Wątek jako obiekt Każdy wątek to obiekt będący instancją klasy Thread. Aby tworzyć aplikacje wykorzystujące współbieżność, obiekty klasy Thread można wykorzystywać na dwa sposoby: 1. Tworzenie, kontrola i zarządzanie obiektem klasy Thread za każdym razem, gdy potrzeba jest wykonania niezależnego zadania. 2. Zarządzanie wątkami wydzielone jest poza zasadniczą część aplikacji. Zadania realizowane przez wątki przekazywane są do tzw. egzekutora (executor).
Definiowanie i uruchamianie wątku Wątki możemy tworzyć na dwa sposoby: 1. Implementacja interfejsu funkcjonalnego Runnable posiadającego metodę run odpowiedzialną za wykonanie kodu wątku. public class MojWatek implements Runnable public void run() System.out.println( Działa wątek! ); public static void main(string args[]) Thread watek = new Thread(new MojWatek()); watek.start();
Definiowanie wątku 2. Dziedziczenie z klasy Thread. public class MojWatek extends Thread public void run() System.out.println( Działa wątek! ); public static void main(string args[]) MojWatek watek = new MojWatek(); watek.start();
Usypianie wątku Metoda sleep klasy Thread powoduje zatrzymanie działania wątku na określony czas, dając w ten sposób możliwość działania innym nieuśpionym wątkom. public class Threads implements Runnable public void run() for (int i = 10; i >=0; --i) System.out.println(i); try Thread.sleep(1000); catch (InterruptedException ex) System.out.println( Błąd! ); public static void main(string[] args) Thread th1 = new Thread(new Threads()); th1.start();
Przerywanie działania wątku Metoda interrupt klasy Thread powoduje przerwanie działania wątku. Metoda interrupted sprawdza czy dany wątek został przerwany. public class Threads implements Runnable public void run() for (int i = 10; i >=0; --i) System.out.println(i); if (Thread.interrupted()) System.out.println("Przerwano działanie!"); return; public static void main(string[] args) Thread th1 = new Thread(new Threads()); Thread th2 = new Thread(new Threads()); th1.start(); th2.start(); th2.interrupt();
Oczekiwanie na zakończenie wątku Metoda join klasy Thread powoduje zatrzymanie działania bieżącego wątku i oczekiwanie na zakończenie działania drugiego wątku (na rzecz którego join została wywołana). public class Threads implements Runnable public void run() for (int i = 10; i >=0; --i) System.out.println(i); try Thread.sleep(1000); catch (InterruptedException ex) System.out.println("Stop!"); public static void main(string[] args) throws InterruptedException Thread th1 = new Thread(new Threads()); Thread th2 = new Thread(new Threads()); th1.start(); th1.join(); th2.start();
Brak synchronizacji Podczas działania wielu wątków, które mają dostęp do tych samych zasobów, brak synchronizacji powoduje ich niestabilność i brak spójności. class Test int x = 0; public int doit() for (int i = 0; i < 1000; i++) x++; x--; return x; class ThreadTest extends Thread Test t; ThreadTest(Test t) this.t = t; public class Threads public static void main(string[] args) Test t = new Test(); ThreadTest tab[] = new ThreadTest[10]; for (int i = 0; i < tab.length; i++) tab[i] = new ThreadTest(t); tab[i].start(); public void run() System.out.println(t.doIt());
Metoda synchronizowana Użycie metody synchronizowanej na rzecz danego obiektu powoduje zablokowanie innych wątków, które mogą działać na tym samym obiekcie. class Test int x = 0; public synchronized int doit() for (int i = 0; i < 1000; i++) x++; x--; return x; class ThreadTest extends Thread Test t; ThreadTest(Test t) this.t = t; public class Threads public static void main(string[] args) Test t = new Test(); ThreadTest tab[] = new ThreadTest[10]; for (int i = 0; i < tab.length; i++) tab[i] = new ThreadTest(t); tab[i].start(); public void run() System.out.println(t.doIt());
Sekcja krytyczna Sekcja krytyczna to fragment kod, który może w danej chwili być wywoływany tylko przez jeden wątek. wprowadza sekcje krytyczne poprzez zastosowanie metod lub bloków synchronizowanych. public int doit() synchronized(this) for (int i = 0; i < 1000; i++) x++; x--; return x;
Niezależne bloki synchronizowane public class Example private long c1 = 0; private long c2 = 0; private Object lock1 = new Object(); private Object lock2 = new Object(); public void inc1() synchronized(lock1) c1++; public void inc2() synchronized(lock2) c2++;
Dziękuję za uwagę!