Commit 067dfbfa by Patryk Czarnik

Ponowne wgranie przykładów dot wątków

parent 51cdd831
package watki.gotowe.ilustracje_nie_do_uruchamiania; package watki.gotowe.ilustracje_nie_do_uruchamiania;
public class Afrykarium1 { public class Afrykarium1 {
// wolne miejsca w środku // wolne miejsca w środku
private int wolne = 2000; private int wolne = 2000;
public synchronized void wpuśćWycieczkę(int ilu) { public synchronized void wpuśćWycieczkę(int ilu) {
try { try {
while(wolne < ilu) { while(wolne < ilu) {
this.wait(); this.wait();
} }
wolne -= ilu; wolne -= ilu;
// otwórz bramki // otwórz bramki
} catch(InterruptedException e) { } catch(InterruptedException e) {
} }
} }
public synchronized void zwiedzającyWychodzi() { public synchronized void zwiedzającyWychodzi() {
wolne++; wolne++;
notify(); notify();
} }
} }
...@@ -5,34 +5,34 @@ import java.util.concurrent.locks.Lock; ...@@ -5,34 +5,34 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
public class Afrykarium2 { public class Afrykarium2 {
// wolne miejsca w środku // wolne miejsca w środku
private int miejsca = 2000; private int miejsca = 2000;
// synchronizacja // synchronizacja
private Lock ochrona = new ReentrantLock(); private Lock ochrona = new ReentrantLock();
private Condition czekanieNaMiejsca = ochrona.newCondition(); private Condition czekanieNaMiejsca = ochrona.newCondition();
public void wpuśćWycieczkę(int ilu) { public void wpuśćWycieczkę(int ilu) {
try { try {
ochrona.lock(); ochrona.lock();
while(miejsca < ilu) { while(miejsca < ilu) {
czekanieNaMiejsca.await(); czekanieNaMiejsca.await();
} }
miejsca -= ilu; miejsca -= ilu;
// otwórz bramki // otwórz bramki
} catch(InterruptedException e) { } catch(InterruptedException e) {
} finally { } finally {
ochrona.unlock(); ochrona.unlock();
} }
} }
public void zwiedzającyWychodzi() { public void zwiedzającyWychodzi() {
try { try {
ochrona.lock(); ochrona.lock();
miejsca++; miejsca++;
czekanieNaMiejsca.signal(); czekanieNaMiejsca.signal();
} finally { } finally {
ochrona.unlock(); ochrona.unlock();
} }
} }
} }
...@@ -3,20 +3,20 @@ package watki.gotowe.ilustracje_nie_do_uruchamiania; ...@@ -3,20 +3,20 @@ package watki.gotowe.ilustracje_nie_do_uruchamiania;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
public class Afrykarium3 { public class Afrykarium3 {
// wolne miejsca w środku // wolne miejsca w środku
private Semaphore miejsca = new Semaphore(2000, true); private Semaphore miejsca = new Semaphore(2000, true);
public void wpuśćWycieczkę(int ilu) { public void wpuśćWycieczkę(int ilu) {
try { try {
// zmniejsza wartość semafora o ilu, // zmniejsza wartość semafora o ilu,
// ale jeśli wartość semafora < ilu, to czeka, aż semafor uzyska odp. wartość. // ale jeśli wartość semafora < ilu, to czeka, aż semafor uzyska odp. wartość.
miejsca.acquire(ilu); // -= akademicko : P miejsca.acquire(ilu); // -= akademicko : P
} catch(InterruptedException e) { } catch(InterruptedException e) {
} }
// otwórz bramki // otwórz bramki
} }
public void zwiedzającyWychodzi() { public void zwiedzającyWychodzi() {
miejsca.release(); // ++ akademicko: V miejsca.release(); // ++ akademicko: V
} }
} }
package watki.gotowe.ilustracje_nie_do_uruchamiania; package watki.gotowe.ilustracje_nie_do_uruchamiania;
public class InstancyjnaIStatyczna { public class InstancyjnaIStatyczna {
synchronized void instancyjna1() { synchronized void instancyjna1() {
} }
synchronized void instancyjna2() { synchronized void instancyjna2() {
// instancyjne synchronizują się na poszczególnych obiektach // instancyjne synchronizują się na poszczególnych obiektach
} }
static synchronized void statyczna1() { static synchronized void statyczna1() {
} }
static synchronized void statyczna2() { static synchronized void statyczna2() {
// statyczne wzajemnie się synchronizują // statyczne wzajemnie się synchronizują
// na obiekcie InstancyjnaIStatyczna.class // na obiekcie InstancyjnaIStatyczna.class
// statyczne i instancyjne wzajemnie się nie synchronizują // statyczne i instancyjne wzajemnie się nie synchronizują
} }
void metoda() { void metoda() {
// gdybym chciał się zsynchronizować z metodami statycznymi, to mogę tak: // gdybym chciał się zsynchronizować z metodami statycznymi, to mogę tak:
synchronized(InstancyjnaIStatyczna.class) { synchronized(InstancyjnaIStatyczna.class) {
} }
// tak jak // tak jak
synchronized(this) { synchronized(this) {
// jest synchronizacją na bieżącym obiekcie // jest synchronizacją na bieżącym obiekcie
// z tym że tutaj i tak nic nie robi, bo jesteśmy w metodzie synchronized // z tym że tutaj i tak nic nie robi, bo jesteśmy w metodzie synchronized
} }
} }
} }
package watki.gotowe.kolekcje; package watki.gotowe.kolekcje;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.*;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
/* W tym przykładzie porównuję szybkość działania ConcurrentHashMap i zwykłwej HashMap opakowanej w synchronizedMap. /* W tym przykładzie porównuję szybkość działania ConcurrentHashMap i zwykłej HashMap opakowanej w synchronizedMap.
* Program tworzy N wątków, które operują na słowniku String→Integer w taki sposób, że * Program tworzy N wątków, które operują na słowniku String→Integer w taki sposób, że
* - losują liczbę od 1 do K - po konwersji na tekst staje się ona kluczem w słowniku, * - losują liczbę od 1 do K - po konwersji na tekst staje się ona kluczem w słowniku,
* - wykonują operację modyfikacji zawartości słownika pod tym kluczem; aby koszt losowania itp. nie zaszumił kosztu samej mapy, operacja jest powtarzana kilkukrotnie z tym samym kluczem. * - wykonują operację modyfikacji zawartości słownika pod tym kluczem; aby koszt losowania itp. nie zaszumił kosztu samej mapy, operacja jest powtarzana kilkukrotnie z tym samym kluczem.
*/ */
public class ConcMap { public class ConcMap {
// liczba wątków // liczba wątków
private static final int N = 16; private static final int N = 16;
// wielkość słownika // wielkość słownika
private static final int K = 100; private static final int K = 100;
// ilość powtórzeń jednej operacji // ilość powtórzeń jednej operacji
private static final int P = 50; private static final int P = 50;
// ilość powtórzeń całości // ilość powtórzeń całości
private static final int R = 10_000; private static final int R = 10_000;
// odkomentuj jedną z wersji i sprawdź // odkomentuj jedną z wersji i sprawdź
//private final Map<String, Integer> map = Collections.synchronizedMap(new HashMap<>()); //private final Map<String, Integer> map = Collections.synchronizedMap(new HashMap<>());
private final Map<String, Integer> map = new ConcurrentHashMap<>(); private final Map<String, Integer> map = new ConcurrentHashMap<>();
//private final ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); //private final ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>();
private void dzialaj() { private void dzialaj() {
final ThreadLocalRandom random = ThreadLocalRandom.current(); final ThreadLocalRandom random = ThreadLocalRandom.current();
for(int r=0; r < R; r++) { for(int r=0; r < R; r++) {
final int k = random.nextInt(K); final int k = random.nextInt(K);
final int d = random.nextInt(1000) - 500; final int d = random.nextInt(1000) - 500;
final String key = String.valueOf(k); final String key = String.valueOf(k);
for(int p = 0; p < P; p++) { for(int p = 0; p < P; p++) {
Integer v = map.merge(key, d, (x, y) -> x+y); Integer v = map.merge(key, d, (x, y) -> x+y);
//System.out.println(r + " " + p); //System.out.println(r + " " + p);
} }
} }
} }
public static void main(String[] args) { public static void main(String[] args) {
ConcMap instance = new ConcMap(); ConcMap instance = new ConcMap();
ExecutorService pool = Executors.newFixedThreadPool(N); ExecutorService pool = Executors.newFixedThreadPool(N);
System.out.println("Start"); System.out.println("Start");
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
for(int i = 0; i < N; i++) { for(int i = 0; i < N; i++) {
pool.submit(instance::dzialaj); pool.submit(instance::dzialaj);
} }
try { try {
pool.shutdown(); pool.shutdown();
pool.awaitTermination(1, TimeUnit.HOURS); pool.awaitTermination(1, TimeUnit.HOURS);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
long end = System.currentTimeMillis(); long end = System.currentTimeMillis();
System.out.println("Czas: " + (end - start)); System.out.println("Czas: " + (end - start));
} }
} }
...@@ -3,8 +3,6 @@ package watki.gotowe.kolekcje; ...@@ -3,8 +3,6 @@ package watki.gotowe.kolekcje;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
...@@ -16,54 +14,54 @@ import java.util.concurrent.TimeUnit; ...@@ -16,54 +14,54 @@ import java.util.concurrent.TimeUnit;
* - wykonują operację modyfikacji zawartości słownika pod tym kluczem; aby koszt losowania itp. nie zaszumił kosztu samej mapy, operacja jest powtarzana kilkukrotnie z tym samym kluczem. * - wykonują operację modyfikacji zawartości słownika pod tym kluczem; aby koszt losowania itp. nie zaszumił kosztu samej mapy, operacja jest powtarzana kilkukrotnie z tym samym kluczem.
*/ */
public class ConcMap_Zwykle { public class ConcMap_Zwykle {
// liczba wątków // liczba wątków
private static final int N = 16; private static final int N = 16;
// wielkość słownika // wielkość słownika
private static final int K = 100; private static final int K = 100;
// ilość powtórzeń jednej operacji // ilość powtórzeń jednej operacji
private static final int P = 50; private static final int P = 50;
// ilość powtórzeń całości // ilość powtórzeń całości
private static final int R = 10_000; private static final int R = 10_000;
// odkomentuj jedną z wersji i sprawdź // odkomentuj jedną z wersji i sprawdź
private final Map<String, Integer> map = Collections.synchronizedMap(new HashMap<>()); private final Map<String, Integer> map = Collections.synchronizedMap(new HashMap<>());
// private final Map<String, Integer> map = new ConcurrentHashMap<>(); // private final Map<String, Integer> map = new ConcurrentHashMap<>();
// private final ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>(); // private final ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>();
private void dzialaj() { private void dzialaj() {
final ThreadLocalRandom random = ThreadLocalRandom.current(); final ThreadLocalRandom random = ThreadLocalRandom.current();
for(int r=0; r < R; r++) { for(int r=0; r < R; r++) {
final int k = random.nextInt(K); final int k = random.nextInt(K);
final int d = random.nextInt(1000) - 500; final int d = random.nextInt(1000) - 500;
final String key = String.valueOf(k); final String key = String.valueOf(k);
for(int p = 0; p < P; p++) { for(int p = 0; p < P; p++) {
Integer v = map.merge(key, d, (x, y) -> x+y); Integer v = map.merge(key, d, (x, y) -> x+y);
//System.out.println(r + " " + p); //System.out.println(r + " " + p);
} }
} }
} }
public static void main(String[] args) { public static void main(String[] args) {
ConcMap_Zwykle instance = new ConcMap_Zwykle(); ConcMap_Zwykle instance = new ConcMap_Zwykle();
ExecutorService pool = Executors.newFixedThreadPool(N); ExecutorService pool = Executors.newFixedThreadPool(N);
System.out.println("Start"); System.out.println("Start");
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
for(int i = 0; i < N; i++) { for(int i = 0; i < N; i++) {
pool.submit(instance::dzialaj); pool.submit(instance::dzialaj);
} }
try { try {
pool.shutdown(); pool.shutdown();
pool.awaitTermination(1, TimeUnit.HOURS); pool.awaitTermination(1, TimeUnit.HOURS);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
long end = System.currentTimeMillis(); long end = System.currentTimeMillis();
System.out.println("Czas: " + (end - start)); System.out.println("Czas: " + (end - start));
} }
} }
...@@ -6,44 +6,44 @@ import java.util.concurrent.CopyOnWriteArrayList; ...@@ -6,44 +6,44 @@ import java.util.concurrent.CopyOnWriteArrayList;
public class CopyArray { public class CopyArray {
public static void main(String[] args) { public static void main(String[] args) {
// Kolekcje "CopyOnWrite" kopiują całą swoją _wewnętrzną_ tablicę gdy tylko ktokolwiek cokolwiek modyfikuje. // Kolekcje "CopyOnWrite" kopiują całą swoją _wewnętrzną_ tablicę gdy tylko ktokolwiek cokolwiek modyfikuje.
// Jeśli wcześniej został utworzony iterator ("ktoś czyta kolekcję"), // Jeśli wcześniej został utworzony iterator ("ktoś czyta kolekcję"),
// to NIE jest on unieważniany, tylko daje obraz kolekcji sprzed zmiany ("snapshot"). // to NIE jest on unieważniany, tylko daje obraz kolekcji sprzed zmiany ("snapshot").
// Iteratory NIE wyrzucają ConcurrrentModificationException. // Iteratory NIE wyrzucają ConcurrrentModificationException.
// Iteratory dają dostęp tylko do odczytu. // Iteratory dają dostęp tylko do odczytu.
List<String> lista = new CopyOnWriteArrayList<>(); List<String> lista = new CopyOnWriteArrayList<>();
lista.add("Ala"); lista.add("Ala");
lista.add("Basia"); lista.add("Basia");
lista.add("Celina"); lista.add("Celina");
Iterator<String> it1 = lista.iterator(); Iterator<String> it1 = lista.iterator();
lista.add("Dorota"); lista.add("Dorota");
lista.add("Eliza"); lista.add("Eliza");
Iterator<String> it2 = lista.iterator(); Iterator<String> it2 = lista.iterator();
lista.add("Felicja"); lista.add("Felicja");
lista.add("Grażyna"); lista.add("Grażyna");
System.out.print("it1: "); System.out.print("it1: ");
while(it1.hasNext()) { while(it1.hasNext()) {
System.out.print(it1.next() + " "); System.out.print(it1.next() + " ");
} }
System.out.println(); System.out.println();
System.out.print("it2: "); System.out.print("it2: ");
while(it2.hasNext()) { while(it2.hasNext()) {
System.out.print(it2.next() + " "); System.out.print(it2.next() + " ");
// it2.remove(); // EXN // it2.remove(); // EXN
} }
System.out.println(); System.out.println();
System.out.print("lista: "); System.out.print("lista: ");
for(String x : lista) { for(String x : lista) {
System.out.print(x + " "); System.out.print(x + " ");
} }
System.out.println(); System.out.println();
} }
} }
package watki.gotowe.kolekcje; package watki.gotowe.kolekcje;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
public class OpakowywanieSync { public class OpakowywanieSync {
public static void main(String[] args) { public static void main(String[] args) {
// Vector, Hashtable, StringBuffer - stare klasy Javy, które są "thread-safe" // Vector, Hashtable, StringBuffer - stare klasy Javy, które są "thread-safe"
StringBuffer s; StringBuffer s;
Vector v; Vector v;
Hashtable h; Hashtable h;
// Współczesne ich wersje bez synchronizacji: StringBuilder, ArrayList, HashMap
List<String> zwykla = new ArrayList<>();
zwykla.add("Ala"); List<String> zwykla = new ArrayList<>();
zwykla.add("Ola"); zwykla.add("Ala");
zwykla.add("Ela"); zwykla.add("Ola");
zwykla.add("Ela");
List<String> synchronizowana = Collections.synchronizedList(zwykla);
System.out.println(synchronizowana.getClass()); List<String> synchronizowana = Collections.synchronizedList(zwykla);
System.out.println("Zawartość zwykłej: " + zwykla); System.out.println(synchronizowana.getClass());
System.out.println("Zawartość synchr: " + synchronizowana); System.out.println("Zawartość zwykłej: " + zwykla);
System.out.println(); System.out.println("Zawartość synchr: " + synchronizowana);
System.out.println();
zwykla.add("Ula");
synchronizowana.add("Ewa"); zwykla.add("Ula");
System.out.println("Zawartość zwykłej: " + zwykla); synchronizowana.add("Ewa");
System.out.println("Zawartość synchr: " + synchronizowana); System.out.println("Zawartość zwykłej: " + zwykla);
System.out.println("Zawartość synchr: " + synchronizowana);
// Natomiast złą praktyką byłoby bezpośrednie korzystanie ze zmiennej zwykla.
// Dlatego najlepiej od razu tworzyć zmienną listową w taki sposób: // Natomiast złą praktyką byłoby bezpośrednie korzystanie ze zmiennej zwykla.
List<String> synchronizowana2 = Collections.synchronizedList(new ArrayList<>()); // Dlatego najlepiej od razu tworzyć zmienną listową w taki sposób:
List<String> synchronizowana2 = Collections.synchronizedList(new ArrayList<>());
// Jeśli wątek wykonuje kilka operacji pod rząd, to są one synchronizowane KAŻDA OSOBNO
// Przykład błedu: // Jeśli wątek wykonuje kilka operacji pod rząd, to są one synchronizowane KAŻDA OSOBNO
// Jeśli wiele wątków będzie wykonywać taki kod, to dwa wątki mogą usuwać element z jednoelementowej listy -> błąd // Przykład błędu:
if(synchronizowana.size() > 0) { // Jeśli wiele wątków będzie wykonywać taki kod, to dwa wątki mogą usuwać element z jednoelementowej listy -> błąd
// tutaj może coś zrobić inny wątek if(synchronizowana.size() > 0) {
synchronizowana.remove(0); // tutaj może coś zrobić inny wątek
} synchronizowana.remove(0);
}
// Zalecanym podejściem jest wtedy wzięcie całej serii operacji w blok synchronizowany na obiekcie listy:
synchronized(synchronizowana) { // Zalecanym podejściem jest wtedy wzięcie całej serii operacji w blok synchronizowany na obiekcie listy:
// skomplikowane operacje na liście... synchronized(synchronizowana) {
// skomplikowane operacje na liście...
if(synchronizowana.size() > 0) {
// teraz te dwie operacje będą wykonane atomowo if(synchronizowana.size() > 0) {
synchronizowana.remove(0); // teraz te dwie operacje będą wykonane atomowo
} synchronizowana.remove(0);
}
for (String element : synchronizowana) {
// ... for (String element : synchronizowana) {
// mamy pewność, że w czasie przeglądania inne wątki nie będą ruszać tej listy // ...
} // mamy pewność, że w czasie przeglądania inne wątki nie będą ruszać tej listy
} }
} }
}
} }
...@@ -2,70 +2,68 @@ package watki.gotowe.kolekcje; ...@@ -2,70 +2,68 @@ package watki.gotowe.kolekcje;
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
// Kolejki blokujące mają dodatkowo metody take i put, które działają w sposób blokujący. // Kolejki blokujące mają dodatkowo metody take i put, które działają w sposób blokujący.
public class ProdKons1 { public class ProdKons1 {
private static final int ILE_RAZY = 30; private static final int ILE_RAZY = 30;
private static final int N = 5; private static final int N = 5;
private BlockingQueue<Integer> kolejka = new ArrayBlockingQueue<>(N); private BlockingQueue<Integer> kolejka = new ArrayBlockingQueue<>(N);
public static void main(String[] args) { public static void main(String[] args) {
ProdKons1 program = new ProdKons1(); ProdKons1 program = new ProdKons1();
program.dzialaj(); program.dzialaj();
} }
private void dzialaj() { private void dzialaj() {
Thread producent = new Thread(new Producent()); Thread producent = new Thread(new Producent());
Thread konsument = new Thread(new Konsument()); Thread konsument = new Thread(new Konsument());
System.out.println("Startujemy"); System.out.println("Startujemy");
producent.start(); producent.start();
konsument.start(); konsument.start();
try { try {
producent.join(); producent.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
try { try {
konsument.join(); konsument.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
System.out.println("Koniec. size="+kolejka.size()); System.out.println("Koniec. size="+kolejka.size());
} }
private class Producent implements Runnable { private class Producent implements Runnable {
public void run() { public void run() {
for(int i=1; i<=ILE_RAZY; i++) { for(int i=1; i<=ILE_RAZY; i++) {
int x = (int) (Math.random() * 1000); int x = (int) (Math.random() * 1000);
System.out.println("P: wstawiam " + x); System.out.println("P: wstawiam " + x);
try { try {
kolejka.put(x); kolejka.put(x);
System.out.println("P: Wstawiłem, size=" + kolejka.size() ); System.out.println("P: Wstawiłem, size=" + kolejka.size() );
Thread.sleep(300 + x); Thread.sleep(300 + x);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
} }
private class Konsument implements Runnable { private class Konsument implements Runnable {
public void run() { public void run() {
for(int i=1; i<=ILE_RAZY; i++) { for(int i=1; i<=ILE_RAZY; i++) {
try { try {
Thread.sleep(100); Thread.sleep(100);
System.out.println(" K: Biorę..."); System.out.println(" K: Biorę...");
int x = kolejka.take(); int x = kolejka.take();
//int x = kolejka.poll(100, TimeUnit.DAYS); //int x = kolejka.poll(100, TimeUnit.DAYS);
System.out.println(" K: ... Pobrałem " + x); System.out.println(" K: ... Pobrałem " + x);
Thread.sleep(2*x); Thread.sleep(2*x);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
} }
} }
...@@ -4,60 +4,60 @@ import java.util.concurrent.BlockingQueue; ...@@ -4,60 +4,60 @@ import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
public class ProdKons2 { public class ProdKons2 {
private static final int ILE_RAZY = 30; private static final int ILE_RAZY = 30;
private BlockingQueue<Integer> kolejka = new LinkedBlockingQueue<>(); private BlockingQueue<Integer> kolejka = new LinkedBlockingQueue<>();
public static void main(String[] args) { public static void main(String[] args) {
ProdKons2 program = new ProdKons2(); ProdKons2 program = new ProdKons2();
program.dzialaj(); program.dzialaj();
} }
private void dzialaj() { private void dzialaj() {
Thread producent = new Thread(new Producent()); Thread producent = new Thread(new Producent());
Thread konsument = new Thread(new Konsument()); Thread konsument = new Thread(new Konsument());
System.out.println("Startujemy"); System.out.println("Startujemy");
producent.start(); producent.start();
konsument.start(); konsument.start();
try { try {
producent.join(); producent.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
try { try {
konsument.join(); konsument.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
System.out.println("Koniec. size="+kolejka.size()); System.out.println("Koniec. size="+kolejka.size());
} }
private class Producent implements Runnable { private class Producent implements Runnable {
public void run() { public void run() {
for(int i=1; i<=ILE_RAZY; i++) { for(int i=1; i<=ILE_RAZY; i++) {
int x = (int) (Math.random() * 1000); int x = (int) (Math.random() * 1000);
System.out.println("P: wstawiam " + x); System.out.println("P: wstawiam " + x);
try { try {
kolejka.put(x); kolejka.put(x);
System.out.println("P: Wstawiłem, size=" + kolejka.size() ); System.out.println("P: Wstawiłem, size=" + kolejka.size() );
Thread.sleep(300 + x); Thread.sleep(300 + x);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
} }
private class Konsument implements Runnable { private class Konsument implements Runnable {
public void run() { public void run() {
for(int i=1; i<=ILE_RAZY; i++) { for(int i=1; i<=ILE_RAZY; i++) {
try { try {
Thread.sleep(100); Thread.sleep(100);
System.out.println(" K: Biorę..."); System.out.println(" K: Biorę...");
int x = kolejka.take(); int x = kolejka.take();
System.out.println(" K: ... Pobrałem " + x); System.out.println(" K: ... Pobrałem " + x);
Thread.sleep(2*x); Thread.sleep(2*x);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
} }
} }
package watki.gotowe.konta.v1_brak_synchronizacji; package watki.gotowe.konta.v1_brak_synchronizacji;
public class BrakSrodkow extends Exception { public class BrakSrodkow extends Exception {
private static final long serialVersionUID = 5262944731342409658L; private static final long serialVersionUID = 5262944731342409658L;
public BrakSrodkow() { public BrakSrodkow() {
super(); super();
} }
public BrakSrodkow(String message) { public BrakSrodkow(String message) {
super(message); super(message);
} }
} }
package watki.gotowe.konta.v1_brak_synchronizacji; package watki.gotowe.konta.v1_brak_synchronizacji;
class Konto { class Konto {
private final int numer; private final int numer;
private int saldo; private int saldo;
private Osoba wlasciciel; private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) { public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer; this.numer = numer;
this.saldo = saldo; this.saldo = saldo;
this.wlasciciel = wlasciciel; this.wlasciciel = wlasciciel;
} }
public Osoba getWlasciciel() { public Osoba getWlasciciel() {
return wlasciciel; return wlasciciel;
} }
public void setWlasciciel(Osoba wlasciciel) { public void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel; this.wlasciciel = wlasciciel;
} }
public int getNumer() { public int getNumer() {
return numer; return numer;
} }
public int getSaldo() { public int getSaldo() {
return saldo; return saldo;
} }
public String toString() { public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel; return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel;
} }
public void wplata(int kwota) { public void wplata(int kwota) {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
} }
saldo += kwota; saldo += kwota;
} }
public void wyplata(int kwota) throws BrakSrodkow { public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
} }
if(kwota > saldo) { if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer); throw new BrakSrodkow("Brak środków na koncie nr " + numer);
} }
saldo -= kwota; saldo -= kwota;
} }
} }
...@@ -4,63 +4,63 @@ import java.time.LocalDate; ...@@ -4,63 +4,63 @@ import java.time.LocalDate;
import java.time.Period; import java.time.Period;
class Osoba { class Osoba {
private String imie, nazwisko; private String imie, nazwisko;
private LocalDate dataUrodzenia; private LocalDate dataUrodzenia;
public Osoba() { public Osoba() {
} }
Osoba(String imie, String nazwisko) { Osoba(String imie, String nazwisko) {
this.imie = imie; this.imie = imie;
this.nazwisko = nazwisko; this.nazwisko = nazwisko;
} }
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) { public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.setImie(imie); this.setImie(imie);
this.nazwisko = nazwisko; this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia; this.dataUrodzenia = dataUrodzenia;
} }
public Osoba(String imie, String nazwisko, String dataUrodzenia) { public Osoba(String imie, String nazwisko, String dataUrodzenia) {
// wywołanie innego konstruktora z tej samej klasy // wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, LocalDate.parse(dataUrodzenia)); this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
} }
public int obliczWiek() { public int obliczWiek() {
LocalDate dzisiaj = LocalDate.now(); LocalDate dzisiaj = LocalDate.now();
Period wiek = Period.between(dataUrodzenia, dzisiaj); Period wiek = Period.between(dataUrodzenia, dzisiaj);
return wiek.getYears(); return wiek.getYears();
} }
@Override @Override
public String toString() { public String toString() {
return imie + " " +nazwisko + " ur." + dataUrodzenia; return imie + " " +nazwisko + " ur." + dataUrodzenia;
} }
public String kimJestes() { public String kimJestes() {
return "Jestem osobą"; return "Jestem osobą";
} }
public String getImie() { public String getImie() {
return imie; return imie;
} }
public String getNazwisko() { public String getNazwisko() {
return nazwisko; return nazwisko;
} }
public LocalDate getDataUrodzenia() { public LocalDate getDataUrodzenia() {
return dataUrodzenia; return dataUrodzenia;
} }
public void setImie(String imie) { public void setImie(String imie) {
if(imie == null || imie.isEmpty()) { if(imie == null || imie.isEmpty()) {
throw new IllegalArgumentException("imię nie może być puste"); throw new IllegalArgumentException("imię nie może być puste");
} }
this.imie = imie; this.imie = imie;
} }
public void setNazwisko(String nazwisko) { public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko; this.nazwisko = nazwisko;
} }
} }
...@@ -4,45 +4,45 @@ import java.time.LocalDate; ...@@ -4,45 +4,45 @@ import java.time.LocalDate;
class Przeploty { class Przeploty {
public static void main(String[] args) { public static void main(String[] args) {
final int N = 100_000; final int N = 100_000;
final int KWOTA = 10; final int KWOTA = 10;
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now()); Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now());
Konto konto = new Konto(1, 1000_000, ala); Konto konto = new Konto(1, 1000_000, ala);
System.out.println(konto); System.out.println(konto);
Thread wplacacz = new Thread(() -> { Thread wplacacz = new Thread(() -> {
for(int i = 0 ; i < N; i++) { for(int i = 0 ; i < N; i++) {
konto.wplata(KWOTA); konto.wplata(KWOTA);
} }
}); });
Thread wyplacacz = new Thread(() -> { Thread wyplacacz = new Thread(() -> {
for(int i = 0; i < N; i++) { for(int i = 0; i < N; i++) {
try { try {
konto.wyplata(KWOTA); konto.wyplata(KWOTA);
} catch (BrakSrodkow e) { } catch (BrakSrodkow e) {
System.err.println(e.getMessage()); System.err.println(e.getMessage());
} }
} }
}); });
System.out.println("Uruchamiam wątki"); System.out.println("Uruchamiam wątki");
wplacacz.start(); wplacacz.start();
wyplacacz.start(); wyplacacz.start();
System.out.println("Czekam na zakończenie"); System.out.println("Czekam na zakończenie");
try { try {
wplacacz.join(); wplacacz.join();
wyplacacz.join(); wyplacacz.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
System.out.println("Wątki zakończone, konto na końcu:"); System.out.println("Wątki zakończone, konto na końcu:");
System.out.println(konto); System.out.println(konto);
} }
} }
...@@ -4,63 +4,63 @@ import java.io.IOException; ...@@ -4,63 +4,63 @@ import java.io.IOException;
class WyplacanieBezOczekiwania { class WyplacanieBezOczekiwania {
static volatile boolean koniec = false; static volatile boolean koniec = false;
public static void main(String[] args) { public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01"); final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala); final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto); System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() { Thread wplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
konto.wplata(1000); konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo()); System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try { try {
Thread.sleep(4000); Thread.sleep(4000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
Thread wyplacacz = new Thread(new Runnable() { Thread wyplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
try { try {
konto.wyplata(100); konto.wyplata(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo()); System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
} catch (BrakSrodkow e) { } catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW"); System.err.println("BRAK ŚRODKÓW");
} }
try { try {
Thread.sleep(200); Thread.sleep(200);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
wplacacz.start(); wplacacz.start();
wyplacacz.start(); wyplacacz.start();
System.out.println("Wątki wystartowały"); System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć"); System.out.println("Naciśnij enter aby zakończyć");
try { try {
System.in.read(); System.in.read();
} catch (IOException e1) { } catch (IOException e1) {
} }
koniec = true; koniec = true;
try { try {
wplacacz.join(); wplacacz.join();
wyplacacz.join(); wyplacacz.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.err.println("INTERRUPTED"); System.err.println("INTERRUPTED");
} }
System.out.println("na końcu: " + konto); System.out.println("na końcu: " + konto);
} }
} }
package watki.gotowe.konta.v2_synchronizacja_metod; package watki.gotowe.konta.v2_synchronizacja_metod;
public class BrakSrodkow extends Exception { public class BrakSrodkow extends Exception {
private static final long serialVersionUID = 5262944731342409658L; private static final long serialVersionUID = 5262944731342409658L;
public BrakSrodkow() { public BrakSrodkow() {
super(); super();
} }
public BrakSrodkow(String message) { public BrakSrodkow(String message) {
super(message); super(message);
} }
} }
package watki.gotowe.konta.v2_synchronizacja_metod; package watki.gotowe.konta.v2_synchronizacja_metod;
class Konto { class Konto {
private final int numer; private final int numer;
private int saldo; private int saldo;
private Osoba wlasciciel; private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) { public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer; this.numer = numer;
this.saldo = saldo; this.saldo = saldo;
this.wlasciciel = wlasciciel; this.wlasciciel = wlasciciel;
} }
public synchronized Osoba getWlasciciel() { public synchronized Osoba getWlasciciel() {
return wlasciciel; return wlasciciel;
} }
public synchronized void setWlasciciel(Osoba wlasciciel) { public synchronized void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel; this.wlasciciel = wlasciciel;
} }
public int getNumer() { public int getNumer() {
return numer; return numer;
} }
public synchronized int getSaldo() { public synchronized int getSaldo() {
return saldo; return saldo;
} }
public synchronized void wplata(int kwota) { public synchronized void wplata(int kwota) {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
} }
saldo += kwota; saldo += kwota;
notify(); notify();
// System.out.println("I jeszcze coś robię"); // System.out.println("I jeszcze coś robię");
// saldo --; // potrącić prowizję // saldo --; // potrącić prowizję
// wątek obudzony z notify musi jeszcze poczekać, aż ja skończę tu robotę // wątek obudzony z notify musi jeszcze poczekać, aż ja skończę tu robotę
// bo to jeszcze ja zajmuję sekcje "synchorized" // bo to jeszcze ja zajmuję sekcje "synchorized"
} }
public synchronized void wyplata(int kwota) throws BrakSrodkow { public synchronized void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
} }
if(kwota > saldo) { if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer); throw new BrakSrodkow("Brak środków na koncie nr " + numer);
} }
saldo -= kwota; saldo -= kwota;
} }
public synchronized void wyplataCzekaj(int kwota) { public synchronized void wyplataCzekaj(int kwota) {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
} }
try { try {
while(kwota > saldo) { while(kwota > saldo) {
wait(); wait();
// po obudzeniu (notify) ten wątek na normalnych prawach // po obudzeniu (notify) ten wątek na normalnych prawach
// czeka na dostęp do sekcji synchronizowanej // czeka na dostęp do sekcji synchronizowanej
// 1) wątek, który zrobił notify, musi wyjść // 1) wątek, który zrobił notify, musi wyjść
// 2) może pojawić się trzeci wątek, który "wepchnie się" do metody synchronizowanej, // 2) może pojawić się trzeci wątek, który "wepchnie się" do metody synchronizowanej,
// zanim zrobi to TEN wątek obudzony z wait-a // zanim zrobi to TEN wątek obudzony z wait-a
// Również z tego powodu warunek oczekiwania należy sprawdzić ponownie po obudzeniu // Również z tego powodu warunek oczekiwania należy sprawdzić ponownie po obudzeniu
// Standardowy zapis - pętla while. // Standardowy zapis - pętla while.
} }
saldo -= kwota; saldo -= kwota;
notify(); // "budzenie kaskadowe" notify(); // "budzenie kaskadowe"
} catch (InterruptedException e) { } catch (InterruptedException e) {
// Taki wyjątek pojawi się gdy podczas gdy wątek A śpi (w wait, sleep itp.) // Taki wyjątek pojawi się gdy podczas gdy wątek A śpi (w wait, sleep itp.)
// inny wątek B wywoła na wątku A metodę interrupt // inny wątek B wywoła na wątku A metodę interrupt
// Zazwyczaj robi się to, gdy kończy się program albo anuluje wątki, które nie będą potrzebne. // Zazwyczaj robi się to, gdy kończy się program albo anuluje wątki, które nie będą potrzebne.
// interrupt nie jest normalnym zakończeniem oczekiwania. Warunek logiczny nie został spełniony // interrupt nie jest normalnym zakończeniem oczekiwania. Warunek logiczny nie został spełniony
// - w takiej sytuacji nie powinniśmy podejmować akcji zmieniających stan, // - w takiej sytuacji nie powinniśmy podejmować akcji zmieniających stan,
// ani nie powinnismy kontynuować czekania. // ani nie powinnismy kontynuować czekania.
System.err.println(e); System.err.println(e);
} }
} }
public String toString() { public String toString() {
return "Konto nr " + getNumer() + ", saldo: " + getSaldo() + ", wł.: " + getWlasciciel(); return "Konto nr " + getNumer() + ", saldo: " + getSaldo() + ", wł.: " + getWlasciciel();
} }
} }
package watki.gotowe.konta.v2_synchronizacja_metod; package watki.gotowe.konta.v2_synchronizacja_metod;
class Konto_Niepoprawnie { class Konto_Niepoprawnie {
private final int numer; private final int numer;
private int saldo; private int saldo;
private Osoba wlasciciel; private Osoba wlasciciel;
public Konto_Niepoprawnie(int numer, int saldo, Osoba wlasciciel) { public Konto_Niepoprawnie(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer; this.numer = numer;
this.saldo = saldo; this.saldo = saldo;
this.wlasciciel = wlasciciel; this.wlasciciel = wlasciciel;
} }
public synchronized Osoba getWlasciciel() { public synchronized Osoba getWlasciciel() {
return wlasciciel; return wlasciciel;
} }
public synchronized void setWlasciciel(Osoba wlasciciel) { public synchronized void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel; this.wlasciciel = wlasciciel;
} }
public int getNumer() { public int getNumer() {
return numer; return numer;
} }
public synchronized int getSaldo() { public synchronized int getSaldo() {
return saldo; return saldo;
} }
public synchronized void setSaldo(int saldo) { public synchronized void setSaldo(int saldo) {
this.saldo = saldo; this.saldo = saldo;
} }
public String toString() { public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel; return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel;
} }
public void wplata(int kwota) { public void wplata(int kwota) {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
} }
this.setSaldo(this.getSaldo() + kwota); this.setSaldo(this.getSaldo() + kwota);
// Nawet jeśli getter i setter są synchronizowane, to powyższy zapis jest niepoprawny // Nawet jeśli getter i setter są synchronizowane, to powyższy zapis jest niepoprawny
// bo to się tłumaczy na // bo to się tłumaczy na
// int stareSaldo = this.getSaldo(); // int stareSaldo = this.getSaldo();
// int noweSaldo = stareSaldo + kwota; // int noweSaldo = stareSaldo + kwota;
// W TYM momencie inny wątek może też odczytać saldo, zmienić i zapisać // W TYM momencie inny wątek może też odczytać saldo, zmienić i zapisać
// this.setSaldo(noweSaldo); // this.setSaldo(noweSaldo);
// między getem a setem mogą wejść inne wątki // między getem a setem mogą wejść inne wątki
} }
public void wyplata(int kwota) throws BrakSrodkow { public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
} }
if(kwota > saldo) { if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer); throw new BrakSrodkow("Brak środków na koncie nr " + numer);
} }
this.setSaldo(this.getSaldo() - kwota); this.setSaldo(this.getSaldo() - kwota);
} }
} }
...@@ -4,63 +4,63 @@ import java.time.LocalDate; ...@@ -4,63 +4,63 @@ import java.time.LocalDate;
import java.time.Period; import java.time.Period;
class Osoba { class Osoba {
private String imie, nazwisko; private String imie, nazwisko;
private LocalDate dataUrodzenia; private LocalDate dataUrodzenia;
public Osoba() { public Osoba() {
} }
Osoba(String imie, String nazwisko) { Osoba(String imie, String nazwisko) {
this.imie = imie; this.imie = imie;
this.nazwisko = nazwisko; this.nazwisko = nazwisko;
} }
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) { public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.setImie(imie); this.setImie(imie);
this.nazwisko = nazwisko; this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia; this.dataUrodzenia = dataUrodzenia;
} }
public Osoba(String imie, String nazwisko, String dataUrodzenia) { public Osoba(String imie, String nazwisko, String dataUrodzenia) {
// wywołanie innego konstruktora z tej samej klasy // wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, LocalDate.parse(dataUrodzenia)); this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
} }
public int obliczWiek() { public int obliczWiek() {
LocalDate dzisiaj = LocalDate.now(); LocalDate dzisiaj = LocalDate.now();
Period wiek = Period.between(dataUrodzenia, dzisiaj); Period wiek = Period.between(dataUrodzenia, dzisiaj);
return wiek.getYears(); return wiek.getYears();
} }
@Override @Override
public String toString() { public String toString() {
return imie + " " +nazwisko + " ur." + dataUrodzenia; return imie + " " +nazwisko + " ur." + dataUrodzenia;
} }
public String kimJestes() { public String kimJestes() {
return "Jestem osobą"; return "Jestem osobą";
} }
public String getImie() { public String getImie() {
return imie; return imie;
} }
public String getNazwisko() { public String getNazwisko() {
return nazwisko; return nazwisko;
} }
public LocalDate getDataUrodzenia() { public LocalDate getDataUrodzenia() {
return dataUrodzenia; return dataUrodzenia;
} }
public void setImie(String imie) { public void setImie(String imie) {
if(imie == null || imie.isEmpty()) { if(imie == null || imie.isEmpty()) {
throw new IllegalArgumentException("imię nie może być puste"); throw new IllegalArgumentException("imię nie może być puste");
} }
this.imie = imie; this.imie = imie;
} }
public void setNazwisko(String nazwisko) { public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko; this.nazwisko = nazwisko;
} }
} }
...@@ -4,45 +4,45 @@ import java.time.LocalDate; ...@@ -4,45 +4,45 @@ import java.time.LocalDate;
class Przeploty { class Przeploty {
public static void main(String[] args) { public static void main(String[] args) {
final int N = 100_000; final int N = 100_000;
final int KWOTA = 10; final int KWOTA = 10;
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now()); Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now());
Konto konto = new Konto(1, 1000_000, ala); Konto konto = new Konto(1, 1000_000, ala);
System.out.println(konto); System.out.println(konto);
Thread wplacacz = new Thread(() -> { Thread wplacacz = new Thread(() -> {
for(int i = 0 ; i < N; i++) { for(int i = 0 ; i < N; i++) {
konto.wplata(KWOTA); konto.wplata(KWOTA);
} }
}); });
Thread wyplacacz = new Thread(() -> { Thread wyplacacz = new Thread(() -> {
for(int i = 0; i < N; i++) { for(int i = 0; i < N; i++) {
try { try {
konto.wyplata(KWOTA); konto.wyplata(KWOTA);
} catch (BrakSrodkow e) { } catch (BrakSrodkow e) {
System.err.println(e.getMessage()); System.err.println(e.getMessage());
} }
} }
}); });
System.out.println("Uruchamiam wątki"); System.out.println("Uruchamiam wątki");
wplacacz.start(); wplacacz.start();
wyplacacz.start(); wyplacacz.start();
System.out.println("Czekam na zakończenie"); System.out.println("Czekam na zakończenie");
try { try {
wplacacz.join(); wplacacz.join();
wyplacacz.join(); wyplacacz.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
System.out.println("Wątki zakończone, konto na końcu:"); System.out.println("Wątki zakończone, konto na końcu:");
System.out.println(konto); System.out.println(konto);
} }
} }
...@@ -4,63 +4,63 @@ import java.io.IOException; ...@@ -4,63 +4,63 @@ import java.io.IOException;
class WyplacanieBezOczekiwania { class WyplacanieBezOczekiwania {
static volatile boolean koniec = false; static volatile boolean koniec = false;
public static void main(String[] args) { public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01"); final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala); final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto); System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() { Thread wplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
konto.wplata(1000); konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo()); System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try { try {
Thread.sleep(4000); Thread.sleep(4000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
Thread wyplacacz = new Thread(new Runnable() { Thread wyplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
try { try {
konto.wyplata(100); konto.wyplata(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo()); System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
} catch (BrakSrodkow e) { } catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW"); System.err.println("BRAK ŚRODKÓW");
} }
try { try {
Thread.sleep(200); Thread.sleep(200);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
wplacacz.start(); wplacacz.start();
wyplacacz.start(); wyplacacz.start();
System.out.println("Wątki wystartowały"); System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć"); System.out.println("Naciśnij enter aby zakończyć");
try { try {
System.in.read(); System.in.read();
} catch (IOException e1) { } catch (IOException e1) {
} }
koniec = true; koniec = true;
try { try {
wplacacz.join(); wplacacz.join();
wyplacacz.join(); wyplacacz.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.err.println("INTERRUPTED"); System.err.println("INTERRUPTED");
} }
System.out.println("na końcu: " + konto); System.out.println("na końcu: " + konto);
} }
} }
...@@ -4,61 +4,61 @@ import java.io.IOException; ...@@ -4,61 +4,61 @@ import java.io.IOException;
class WyplacanieZOczekiwaniem { class WyplacanieZOczekiwaniem {
static volatile boolean koniec = false; static volatile boolean koniec = false;
public static void main(String[] args) { public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01"); final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala); final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto); System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() { Thread wplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
konto.wplata(1000); konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo()); System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try { try {
Thread.sleep(4000); Thread.sleep(4000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
Thread wyplacacz = new Thread(new Runnable() { Thread wyplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
konto.wyplataCzekaj(100); konto.wyplataCzekaj(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo()); System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
try { try {
Thread.sleep(200); Thread.sleep(200);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
wplacacz.start(); wplacacz.start();
wyplacacz.start(); wyplacacz.start();
System.out.println("Wątki wystartowały"); System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć"); System.out.println("Naciśnij enter aby zakończyć");
try { try {
System.in.read(); System.in.read();
} catch (IOException e1) { } catch (IOException e1) {
} }
koniec = true; koniec = true;
wplacacz.interrupt(); wplacacz.interrupt();
wyplacacz.interrupt(); wyplacacz.interrupt();
try { try {
wplacacz.join(); wplacacz.join();
wyplacacz.join(); wyplacacz.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.err.println("INTERRUPTED"); System.err.println("INTERRUPTED");
} }
System.out.println("na końcu: " + konto); System.out.println("na końcu: " + konto);
} }
} }
package watki.gotowe.konta.v3_synchronizacja_blokow; package watki.gotowe.konta.v3_synchronizacja_blokow;
public class BrakSrodkow extends Exception { public class BrakSrodkow extends Exception {
private static final long serialVersionUID = 5262944731342409658L; private static final long serialVersionUID = 5262944731342409658L;
public BrakSrodkow() { public BrakSrodkow() {
super(); super();
} }
public BrakSrodkow(String message) { public BrakSrodkow(String message) {
super(message); super(message);
} }
} }
package watki.gotowe.konta.v3_synchronizacja_blokow; package watki.gotowe.konta.v3_synchronizacja_blokow;
class Konto { class Konto {
private final int numer; private final int numer;
private int saldo; private int saldo;
private Osoba wlasciciel; private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) { public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer; this.numer = numer;
this.saldo = saldo; this.saldo = saldo;
this.wlasciciel = wlasciciel; this.wlasciciel = wlasciciel;
} }
public synchronized Osoba getWlasciciel() { public synchronized Osoba getWlasciciel() {
return wlasciciel; return wlasciciel;
} }
public synchronized void setWlasciciel(Osoba wlasciciel) { public synchronized void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel; this.wlasciciel = wlasciciel;
} }
public int getNumer() { public int getNumer() {
return numer; return numer;
} }
public synchronized int getSaldo() { public synchronized int getSaldo() {
return saldo; return saldo;
} }
public void wplata(int kwota) { public void wplata(int kwota) {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
} }
synchronized(this) { synchronized(this) {
saldo += kwota; saldo += kwota;
this.notify(); this.notify();
} }
} }
public void wyplata(int kwota) throws BrakSrodkow { public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
} }
// Jeśli mamy warunek i w zależności od warunku zmieniamy dane, // Jeśli mamy warunek i w zależności od warunku zmieniamy dane,
// to warunek i operacja zmiany muszą być RAZEM w jednym bloku synchronizowanym. // to warunek i operacja zmiany muszą być RAZEM w jednym bloku synchronizowanym.
synchronized(this) { synchronized(this) {
if(kwota > saldo) { if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer); throw new BrakSrodkow("Brak środków na koncie nr " + numer);
} }
saldo -= kwota; saldo -= kwota;
} }
} }
public void wyplataCzekaj(int kwota) { public void wyplataCzekaj(int kwota) {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
} }
try { try {
synchronized(this) { synchronized(this) {
while(kwota > saldo) { while(kwota > saldo) {
this.wait(); this.wait();
} }
saldo -= kwota; saldo -= kwota;
this.notify(); this.notify();
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.err.println(e); System.err.println(e);
} }
} }
public String toString() { public String toString() {
return "Konto nr " + getNumer() + ", saldo: " + getSaldo() + ", wł.: " + getWlasciciel(); return "Konto nr " + getNumer() + ", saldo: " + getSaldo() + ", wł.: " + getWlasciciel();
} }
} }
...@@ -4,63 +4,63 @@ import java.time.LocalDate; ...@@ -4,63 +4,63 @@ import java.time.LocalDate;
import java.time.Period; import java.time.Period;
class Osoba { class Osoba {
private String imie, nazwisko; private String imie, nazwisko;
private LocalDate dataUrodzenia; private LocalDate dataUrodzenia;
public Osoba() { public Osoba() {
} }
Osoba(String imie, String nazwisko) { Osoba(String imie, String nazwisko) {
this.imie = imie; this.imie = imie;
this.nazwisko = nazwisko; this.nazwisko = nazwisko;
} }
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) { public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.setImie(imie); this.setImie(imie);
this.nazwisko = nazwisko; this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia; this.dataUrodzenia = dataUrodzenia;
} }
public Osoba(String imie, String nazwisko, String dataUrodzenia) { public Osoba(String imie, String nazwisko, String dataUrodzenia) {
// wywołanie innego konstruktora z tej samej klasy // wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, LocalDate.parse(dataUrodzenia)); this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
} }
public int obliczWiek() { public int obliczWiek() {
LocalDate dzisiaj = LocalDate.now(); LocalDate dzisiaj = LocalDate.now();
Period wiek = Period.between(dataUrodzenia, dzisiaj); Period wiek = Period.between(dataUrodzenia, dzisiaj);
return wiek.getYears(); return wiek.getYears();
} }
@Override @Override
public String toString() { public String toString() {
return imie + " " +nazwisko + " ur." + dataUrodzenia; return imie + " " +nazwisko + " ur." + dataUrodzenia;
} }
public String kimJestes() { public String kimJestes() {
return "Jestem osobą"; return "Jestem osobą";
} }
public String getImie() { public String getImie() {
return imie; return imie;
} }
public String getNazwisko() { public String getNazwisko() {
return nazwisko; return nazwisko;
} }
public LocalDate getDataUrodzenia() { public LocalDate getDataUrodzenia() {
return dataUrodzenia; return dataUrodzenia;
} }
public void setImie(String imie) { public void setImie(String imie) {
if(imie == null || imie.isEmpty()) { if(imie == null || imie.isEmpty()) {
throw new IllegalArgumentException("imię nie może być puste"); throw new IllegalArgumentException("imię nie może być puste");
} }
this.imie = imie; this.imie = imie;
} }
public void setNazwisko(String nazwisko) { public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko; this.nazwisko = nazwisko;
} }
} }
...@@ -4,45 +4,45 @@ import java.time.LocalDate; ...@@ -4,45 +4,45 @@ import java.time.LocalDate;
class Przeploty { class Przeploty {
public static void main(String[] args) { public static void main(String[] args) {
final int N = 100_000; final int N = 100_000;
final int KWOTA = 10; final int KWOTA = 10;
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now()); Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now());
Konto konto = new Konto(1, 1000_000, ala); Konto konto = new Konto(1, 1000_000, ala);
System.out.println(konto); System.out.println(konto);
Thread wplacacz = new Thread(() -> { Thread wplacacz = new Thread(() -> {
for(int i = 0 ; i < N; i++) { for(int i = 0 ; i < N; i++) {
konto.wplata(KWOTA); konto.wplata(KWOTA);
} }
}); });
Thread wyplacacz = new Thread(() -> { Thread wyplacacz = new Thread(() -> {
for(int i = 0; i < N; i++) { for(int i = 0; i < N; i++) {
try { try {
konto.wyplata(KWOTA); konto.wyplata(KWOTA);
} catch (BrakSrodkow e) { } catch (BrakSrodkow e) {
System.err.println(e.getMessage()); System.err.println(e.getMessage());
} }
} }
}); });
System.out.println("Uruchamiam wątki"); System.out.println("Uruchamiam wątki");
wplacacz.start(); wplacacz.start();
wyplacacz.start(); wyplacacz.start();
System.out.println("Czekam na zakończenie"); System.out.println("Czekam na zakończenie");
try { try {
wplacacz.join(); wplacacz.join();
wyplacacz.join(); wyplacacz.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
System.out.println("Wątki zakończone, konto na końcu:"); System.out.println("Wątki zakończone, konto na końcu:");
System.out.println(konto); System.out.println(konto);
} }
} }
...@@ -4,63 +4,63 @@ import java.io.IOException; ...@@ -4,63 +4,63 @@ import java.io.IOException;
class WyplacanieBezOczekiwania { class WyplacanieBezOczekiwania {
static volatile boolean koniec = false; static volatile boolean koniec = false;
public static void main(String[] args) { public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01"); final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala); final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto); System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() { Thread wplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
konto.wplata(1000); konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo()); System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try { try {
Thread.sleep(4000); Thread.sleep(4000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
Thread wyplacacz = new Thread(new Runnable() { Thread wyplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
try { try {
konto.wyplata(100); konto.wyplata(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo()); System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
} catch (BrakSrodkow e) { } catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW"); System.err.println("BRAK ŚRODKÓW");
} }
try { try {
Thread.sleep(200); Thread.sleep(200);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
wplacacz.start(); wplacacz.start();
wyplacacz.start(); wyplacacz.start();
System.out.println("Wątki wystartowały"); System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć"); System.out.println("Naciśnij enter aby zakończyć");
try { try {
System.in.read(); System.in.read();
} catch (IOException e1) { } catch (IOException e1) {
} }
koniec = true; koniec = true;
try { try {
wplacacz.join(); wplacacz.join();
wyplacacz.join(); wyplacacz.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.err.println("INTERRUPTED"); System.err.println("INTERRUPTED");
} }
System.out.println("na końcu: " + konto); System.out.println("na końcu: " + konto);
} }
} }
...@@ -4,59 +4,59 @@ import java.io.IOException; ...@@ -4,59 +4,59 @@ import java.io.IOException;
class WyplacanieZOczekiwaniem { class WyplacanieZOczekiwaniem {
static volatile boolean koniec = false; static volatile boolean koniec = false;
public static void main(String[] args) { public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01"); final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1500, ala); final Konto konto = new Konto(1, 1500, ala);
System.out.println("początek " + konto); System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() { Thread wplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
konto.wplata(1000); konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo()); System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try { try {
Thread.sleep(4000); Thread.sleep(4000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
Thread wyplacacz = new Thread(new Runnable() { Thread wyplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
konto.wyplataCzekaj(100); konto.wyplataCzekaj(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo()); System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
try { try {
Thread.sleep(200); Thread.sleep(200);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
wplacacz.start(); wplacacz.start();
wyplacacz.start(); wyplacacz.start();
System.out.println("Wątki wystartowały"); System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć"); System.out.println("Naciśnij enter aby zakończyć");
try { try {
System.in.read(); System.in.read();
} catch (IOException e1) { } catch (IOException e1) {
} }
koniec = true; koniec = true;
try { try {
wplacacz.join(); wplacacz.join();
wyplacacz.join(); wyplacacz.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.err.println("INTERRUPTED"); System.err.println("INTERRUPTED");
} }
System.out.println("na końcu: " + konto); System.out.println("na końcu: " + konto);
} }
} }
package watki.gotowe.konta.v4_locki; package watki.gotowe.konta.v4_locki;
public class BrakSrodkow extends Exception { public class BrakSrodkow extends Exception {
private static final long serialVersionUID = 5262944731342409658L; private static final long serialVersionUID = 5262944731342409658L;
public BrakSrodkow() { public BrakSrodkow() {
super(); super();
} }
public BrakSrodkow(String message) { public BrakSrodkow(String message) {
super(message); super(message);
} }
} }
...@@ -5,103 +5,102 @@ import java.util.concurrent.locks.Lock; ...@@ -5,103 +5,102 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
class Konto { class Konto {
private final Lock lock = new ReentrantLock(); private final Lock lock = new ReentrantLock();
private final Condition czekanieNaKase = lock.newCondition(); private final Condition czekanieNaKase = lock.newCondition();
// można tworzyć osobne condition związane z oczekiwaniem na różne warunki // można tworzyć osobne condition związane z oczekiwaniem na różne warunki
private final Condition czekanieNaUdzielenieKredytu = lock.newCondition(); private final Condition czekanieNaUdzielenieKredytu = lock.newCondition();
private final int numer; private final int numer;
protected int saldo; protected int saldo;
private Osoba wlasciciel; private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) { public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer; this.numer = numer;
this.saldo = saldo; this.saldo = saldo;
this.wlasciciel = wlasciciel; this.wlasciciel = wlasciciel;
} }
public Osoba getWlasciciel() { public Osoba getWlasciciel() {
try { try {
lock.lock(); lock.lock();
return wlasciciel; return wlasciciel;
} finally { } finally {
lock.unlock(); lock.unlock();
} }
} }
public void setWlasciciel(Osoba wlasciciel) { public void setWlasciciel(Osoba wlasciciel) {
try { try {
lock.lock(); lock.lock();
this.wlasciciel = wlasciciel; this.wlasciciel = wlasciciel;
} finally { } finally {
lock.unlock(); lock.unlock();
} }
} }
public int getNumer() { public int getNumer() {
return numer; return numer;
} }
public int getSaldo() { public int getSaldo() {
lock.lock(); lock.lock();
try { try {
return saldo; return saldo;
} finally { } finally {
lock.unlock(); lock.unlock();
} }
} }
public String toString() { public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel; return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel;
} }
public void wplata(int kwota) { public void wplata(int kwota) {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
} }
lock.lock(); lock.lock();
saldo += kwota; saldo += kwota;
czekanieNaKase.signal(); czekanieNaKase.signal();
lock.unlock(); lock.unlock();
} }
public void wyplata(int kwota) throws BrakSrodkow { public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
} }
lock.lock(); lock.lock();
try { try {
if(kwota > saldo) { if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer); throw new BrakSrodkow("Brak środków na koncie nr " + numer);
} }
saldo -= kwota;
saldo -= kwota; } finally {
} finally { lock.unlock();
lock.unlock(); }
} }
}
public void wyplataCzekaj(int kwota) { public void wyplataCzekaj(int kwota) {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
} }
lock.lock(); lock.lock();
try { try {
while (kwota > saldo) { while (kwota > saldo) {
czekanieNaKase.await(); czekanieNaKase.await();
} }
saldo -= kwota; saldo -= kwota;
czekanieNaKase.signal(); czekanieNaKase.signal();
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
lock.unlock(); lock.unlock();
} }
} }
} }
...@@ -4,63 +4,63 @@ import java.time.LocalDate; ...@@ -4,63 +4,63 @@ import java.time.LocalDate;
import java.time.Period; import java.time.Period;
class Osoba { class Osoba {
private String imie, nazwisko; private String imie, nazwisko;
private LocalDate dataUrodzenia; private LocalDate dataUrodzenia;
public Osoba() { public Osoba() {
} }
Osoba(String imie, String nazwisko) { Osoba(String imie, String nazwisko) {
this.imie = imie; this.imie = imie;
this.nazwisko = nazwisko; this.nazwisko = nazwisko;
} }
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) { public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.setImie(imie); this.setImie(imie);
this.nazwisko = nazwisko; this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia; this.dataUrodzenia = dataUrodzenia;
} }
public Osoba(String imie, String nazwisko, String dataUrodzenia) { public Osoba(String imie, String nazwisko, String dataUrodzenia) {
// wywołanie innego konstruktora z tej samej klasy // wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, LocalDate.parse(dataUrodzenia)); this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
} }
public int obliczWiek() { public int obliczWiek() {
LocalDate dzisiaj = LocalDate.now(); LocalDate dzisiaj = LocalDate.now();
Period wiek = Period.between(dataUrodzenia, dzisiaj); Period wiek = Period.between(dataUrodzenia, dzisiaj);
return wiek.getYears(); return wiek.getYears();
} }
@Override @Override
public String toString() { public String toString() {
return imie + " " +nazwisko + " ur." + dataUrodzenia; return imie + " " +nazwisko + " ur." + dataUrodzenia;
} }
public String kimJestes() { public String kimJestes() {
return "Jestem osobą"; return "Jestem osobą";
} }
public String getImie() { public String getImie() {
return imie; return imie;
} }
public String getNazwisko() { public String getNazwisko() {
return nazwisko; return nazwisko;
} }
public LocalDate getDataUrodzenia() { public LocalDate getDataUrodzenia() {
return dataUrodzenia; return dataUrodzenia;
} }
public void setImie(String imie) { public void setImie(String imie) {
if(imie == null || imie.isEmpty()) { if(imie == null || imie.isEmpty()) {
throw new IllegalArgumentException("imię nie może być puste"); throw new IllegalArgumentException("imię nie może być puste");
} }
this.imie = imie; this.imie = imie;
} }
public void setNazwisko(String nazwisko) { public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko; this.nazwisko = nazwisko;
} }
} }
...@@ -2,16 +2,16 @@ package watki.gotowe.konta.v4_locki; ...@@ -2,16 +2,16 @@ package watki.gotowe.konta.v4_locki;
public class Podklasa extends Konto { public class Podklasa extends Konto {
public Podklasa(int numer, int saldo, Osoba wlasciciel) { public Podklasa(int numer, int saldo, Osoba wlasciciel) {
super(numer, saldo, wlasciciel); super(numer, saldo, wlasciciel);
} }
public void wplata(int kwota) { public void wplata(int kwota) {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
} }
saldo += kwota; saldo += kwota;
} }
} }
...@@ -4,45 +4,45 @@ import java.time.LocalDate; ...@@ -4,45 +4,45 @@ import java.time.LocalDate;
class Przeploty { class Przeploty {
public static void main(String[] args) { public static void main(String[] args) {
final int N = 100_000; final int N = 100_000;
final int KWOTA = 10; final int KWOTA = 10;
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now()); Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now());
Konto konto = new Konto(1, 1000_000, ala); Konto konto = new Konto(1, 1000_000, ala);
System.out.println(konto); System.out.println(konto);
Thread wplacacz = new Thread(() -> { Thread wplacacz = new Thread(() -> {
for(int i = 0 ; i < N; i++) { for(int i = 0 ; i < N; i++) {
konto.wplata(KWOTA); konto.wplata(KWOTA);
} }
}); });
Thread wyplacacz = new Thread(() -> { Thread wyplacacz = new Thread(() -> {
for(int i = 0; i < N; i++) { for(int i = 0; i < N; i++) {
try { try {
konto.wyplata(KWOTA); konto.wyplata(KWOTA);
} catch (BrakSrodkow e) { } catch (BrakSrodkow e) {
System.err.println(e.getMessage()); System.err.println(e.getMessage());
} }
} }
}); });
System.out.println("Uruchamiam wątki"); System.out.println("Uruchamiam wątki");
wplacacz.start(); wplacacz.start();
wyplacacz.start(); wyplacacz.start();
System.out.println("Czekam na zakończenie"); System.out.println("Czekam na zakończenie");
try { try {
wplacacz.join(); wplacacz.join();
wyplacacz.join(); wyplacacz.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
System.out.println("Wątki zakończone, konto na końcu:"); System.out.println("Wątki zakończone, konto na końcu:");
System.out.println(konto); System.out.println(konto);
} }
} }
...@@ -4,63 +4,63 @@ import java.io.IOException; ...@@ -4,63 +4,63 @@ import java.io.IOException;
class WyplacanieBezOczekiwania { class WyplacanieBezOczekiwania {
static volatile boolean koniec = false; static volatile boolean koniec = false;
public static void main(String[] args) { public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01"); final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala); final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto); System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() { Thread wplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
konto.wplata(1000); konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo()); System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try { try {
Thread.sleep(4000); Thread.sleep(4000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
Thread wyplacacz = new Thread(new Runnable() { Thread wyplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
try { try {
konto.wyplata(100); konto.wyplata(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo()); System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
} catch (BrakSrodkow e) { } catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW"); System.err.println("BRAK ŚRODKÓW");
} }
try { try {
Thread.sleep(200); Thread.sleep(200);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
wplacacz.start(); wplacacz.start();
wyplacacz.start(); wyplacacz.start();
System.out.println("Wątki wystartowały"); System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć"); System.out.println("Naciśnij enter aby zakończyć");
try { try {
System.in.read(); System.in.read();
} catch (IOException e1) { } catch (IOException e1) {
} }
koniec = true; koniec = true;
try { try {
wplacacz.join(); wplacacz.join();
wyplacacz.join(); wyplacacz.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.err.println("INTERRUPTED"); System.err.println("INTERRUPTED");
} }
System.out.println("na końcu: " + konto); System.out.println("na końcu: " + konto);
} }
} }
...@@ -4,59 +4,59 @@ import java.io.IOException; ...@@ -4,59 +4,59 @@ import java.io.IOException;
class WyplacanieZOczekiwaniem { class WyplacanieZOczekiwaniem {
static volatile boolean koniec = false; static volatile boolean koniec = false;
public static void main(String[] args) { public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01"); final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala); final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto); System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() { Thread wplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
konto.wplata(1000); konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo()); System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try { try {
Thread.sleep(4000); Thread.sleep(4000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
Thread wyplacacz = new Thread(new Runnable() { Thread wyplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
konto.wyplataCzekaj(100); konto.wyplataCzekaj(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo()); System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
try { try {
Thread.sleep(200); Thread.sleep(200);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
wplacacz.start(); wplacacz.start();
wyplacacz.start(); wyplacacz.start();
System.out.println("Wątki wystartowały"); System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć"); System.out.println("Naciśnij enter aby zakończyć");
try { try {
System.in.read(); System.in.read();
} catch (IOException e1) { } catch (IOException e1) {
} }
koniec = true; koniec = true;
try { try {
wplacacz.join(); wplacacz.join();
wyplacacz.join(); wyplacacz.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.err.println("INTERRUPTED"); System.err.println("INTERRUPTED");
} }
System.out.println("na końcu: " + konto); System.out.println("na końcu: " + konto);
} }
} }
package watki.gotowe.konta.v5_semafor; package watki.gotowe.konta.v5_semafor;
public class BrakSrodkow extends Exception { public class BrakSrodkow extends Exception {
private static final long serialVersionUID = 5262944731342409658L; private static final long serialVersionUID = 5262944731342409658L;
public BrakSrodkow() { public BrakSrodkow() {
super(); super();
} }
public BrakSrodkow(String message) { public BrakSrodkow(String message) {
super(message); super(message);
} }
} }
...@@ -8,95 +8,95 @@ import java.util.concurrent.Semaphore; ...@@ -8,95 +8,95 @@ import java.util.concurrent.Semaphore;
* ale w Javie nadają się tam, gdzie trzeba "liczyć zasoby" (zob. Afrykarium3). * ale w Javie nadają się tam, gdzie trzeba "liczyć zasoby" (zob. Afrykarium3).
*/ */
class Konto { class Konto {
private final Semaphore mutex = new Semaphore(1); private final Semaphore mutex = new Semaphore(1);
private final Semaphore kasa = new Semaphore(0); private final Semaphore kasa = new Semaphore(0);
private int iluCzekaNaKase = 0; private int iluCzekaNaKase = 0;
private final int numer; private final int numer;
protected int saldo; protected int saldo;
private Osoba wlasciciel; private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) { public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer; this.numer = numer;
this.saldo = saldo; this.saldo = saldo;
this.wlasciciel = wlasciciel; this.wlasciciel = wlasciciel;
} }
public Osoba getWlasciciel() { public Osoba getWlasciciel() {
return wlasciciel; return wlasciciel;
} }
public void setWlasciciel(Osoba wlasciciel) { public void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel; this.wlasciciel = wlasciciel;
} }
public int getNumer() { public int getNumer() {
return numer; return numer;
} }
public int getSaldo() { public int getSaldo() {
return saldo; return saldo;
} }
public String toString() { public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel; return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel;
} }
public void wplata(int kwota) { public void wplata(int kwota) {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
} }
try { try {
mutex.acquire(); mutex.acquire();
saldo += kwota; saldo += kwota;
if(iluCzekaNaKase > 0) { if(iluCzekaNaKase > 0) {
kasa.release(); kasa.release();
} else { } else {
mutex.release(); mutex.release();
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
mutex.release(); mutex.release();
} }
} }
public void wyplata(int kwota) throws BrakSrodkow { public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
} }
try { try {
mutex.acquire(); mutex.acquire();
if(kwota > saldo) { if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer); throw new BrakSrodkow("Brak środków na koncie nr " + numer);
} }
saldo -= kwota; saldo -= kwota;
} catch (InterruptedException e) { } catch (InterruptedException e) {
} finally { } finally {
mutex.release(); mutex.release();
} }
} }
public void wyplataCzekaj(int kwota) { public void wyplataCzekaj(int kwota) {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
} }
try { try {
mutex.acquire(); mutex.acquire();
while (kwota > saldo) { while (kwota > saldo) {
iluCzekaNaKase++; iluCzekaNaKase++;
mutex.release(); mutex.release();
kasa.acquire(); kasa.acquire();
iluCzekaNaKase--; iluCzekaNaKase--;
} }
saldo -= kwota; saldo -= kwota;
} catch (InterruptedException e) { } catch (InterruptedException e) {
} finally { } finally {
mutex.release(); mutex.release();
} }
} }
} }
...@@ -4,63 +4,63 @@ import java.time.LocalDate; ...@@ -4,63 +4,63 @@ import java.time.LocalDate;
import java.time.Period; import java.time.Period;
class Osoba { class Osoba {
private String imie, nazwisko; private String imie, nazwisko;
private LocalDate dataUrodzenia; private LocalDate dataUrodzenia;
public Osoba() { public Osoba() {
} }
Osoba(String imie, String nazwisko) { Osoba(String imie, String nazwisko) {
this.imie = imie; this.imie = imie;
this.nazwisko = nazwisko; this.nazwisko = nazwisko;
} }
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) { public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.setImie(imie); this.setImie(imie);
this.nazwisko = nazwisko; this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia; this.dataUrodzenia = dataUrodzenia;
} }
public Osoba(String imie, String nazwisko, String dataUrodzenia) { public Osoba(String imie, String nazwisko, String dataUrodzenia) {
// wywołanie innego konstruktora z tej samej klasy // wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, LocalDate.parse(dataUrodzenia)); this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
} }
public int obliczWiek() { public int obliczWiek() {
LocalDate dzisiaj = LocalDate.now(); LocalDate dzisiaj = LocalDate.now();
Period wiek = Period.between(dataUrodzenia, dzisiaj); Period wiek = Period.between(dataUrodzenia, dzisiaj);
return wiek.getYears(); return wiek.getYears();
} }
@Override @Override
public String toString() { public String toString() {
return imie + " " +nazwisko + " ur." + dataUrodzenia; return imie + " " +nazwisko + " ur." + dataUrodzenia;
} }
public String kimJestes() { public String kimJestes() {
return "Jestem osobą"; return "Jestem osobą";
} }
public String getImie() { public String getImie() {
return imie; return imie;
} }
public String getNazwisko() { public String getNazwisko() {
return nazwisko; return nazwisko;
} }
public LocalDate getDataUrodzenia() { public LocalDate getDataUrodzenia() {
return dataUrodzenia; return dataUrodzenia;
} }
public void setImie(String imie) { public void setImie(String imie) {
if(imie == null || imie.isEmpty()) { if(imie == null || imie.isEmpty()) {
throw new IllegalArgumentException("imię nie może być puste"); throw new IllegalArgumentException("imię nie może być puste");
} }
this.imie = imie; this.imie = imie;
} }
public void setNazwisko(String nazwisko) { public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko; this.nazwisko = nazwisko;
} }
} }
...@@ -2,16 +2,16 @@ package watki.gotowe.konta.v5_semafor; ...@@ -2,16 +2,16 @@ package watki.gotowe.konta.v5_semafor;
public class Podklasa extends Konto { public class Podklasa extends Konto {
public Podklasa(int numer, int saldo, Osoba wlasciciel) { public Podklasa(int numer, int saldo, Osoba wlasciciel) {
super(numer, saldo, wlasciciel); super(numer, saldo, wlasciciel);
} }
public void wplata(int kwota) { public void wplata(int kwota) {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
} }
saldo += kwota; saldo += kwota;
} }
} }
...@@ -4,45 +4,45 @@ import java.time.LocalDate; ...@@ -4,45 +4,45 @@ import java.time.LocalDate;
class Przeploty { class Przeploty {
public static void main(String[] args) { public static void main(String[] args) {
final int N = 100_000; final int N = 100_000;
final int KWOTA = 10; final int KWOTA = 10;
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now()); Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now());
Konto konto = new Konto(1, 1000_000, ala); Konto konto = new Konto(1, 1000_000, ala);
System.out.println(konto); System.out.println(konto);
Thread wplacacz = new Thread(() -> { Thread wplacacz = new Thread(() -> {
for(int i = 0 ; i < N; i++) { for(int i = 0 ; i < N; i++) {
konto.wplata(KWOTA); konto.wplata(KWOTA);
} }
}); });
Thread wyplacacz = new Thread(() -> { Thread wyplacacz = new Thread(() -> {
for(int i = 0; i < N; i++) { for(int i = 0; i < N; i++) {
try { try {
konto.wyplata(KWOTA); konto.wyplata(KWOTA);
} catch (BrakSrodkow e) { } catch (BrakSrodkow e) {
System.err.println(e.getMessage()); System.err.println(e.getMessage());
} }
} }
}); });
System.out.println("Uruchamiam wątki"); System.out.println("Uruchamiam wątki");
wplacacz.start(); wplacacz.start();
wyplacacz.start(); wyplacacz.start();
System.out.println("Czekam na zakończenie"); System.out.println("Czekam na zakończenie");
try { try {
wplacacz.join(); wplacacz.join();
wyplacacz.join(); wyplacacz.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
System.out.println("Wątki zakończone, konto na końcu:"); System.out.println("Wątki zakończone, konto na końcu:");
System.out.println(konto); System.out.println(konto);
} }
} }
...@@ -4,63 +4,63 @@ import java.io.IOException; ...@@ -4,63 +4,63 @@ import java.io.IOException;
class WyplacanieBezOczekiwania { class WyplacanieBezOczekiwania {
static volatile boolean koniec = false; static volatile boolean koniec = false;
public static void main(String[] args) { public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01"); final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala); final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto); System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() { Thread wplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
konto.wplata(1000); konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo()); System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try { try {
Thread.sleep(4000); Thread.sleep(4000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
Thread wyplacacz = new Thread(new Runnable() { Thread wyplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
try { try {
konto.wyplata(100); konto.wyplata(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo()); System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
} catch (BrakSrodkow e) { } catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW"); System.err.println("BRAK ŚRODKÓW");
} }
try { try {
Thread.sleep(200); Thread.sleep(200);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
wplacacz.start(); wplacacz.start();
wyplacacz.start(); wyplacacz.start();
System.out.println("Wątki wystartowały"); System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć"); System.out.println("Naciśnij enter aby zakończyć");
try { try {
System.in.read(); System.in.read();
} catch (IOException e1) { } catch (IOException e1) {
} }
koniec = true; koniec = true;
try { try {
wplacacz.join(); wplacacz.join();
wyplacacz.join(); wyplacacz.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.err.println("INTERRUPTED"); System.err.println("INTERRUPTED");
} }
System.out.println("na końcu: " + konto); System.out.println("na końcu: " + konto);
} }
} }
...@@ -4,59 +4,59 @@ import java.io.IOException; ...@@ -4,59 +4,59 @@ import java.io.IOException;
class WyplacanieZOczekiwaniem { class WyplacanieZOczekiwaniem {
static volatile boolean koniec = false; static volatile boolean koniec = false;
public static void main(String[] args) { public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01"); final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala); final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto); System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() { Thread wplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
konto.wplata(1000); konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo()); System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try { try {
Thread.sleep(4000); Thread.sleep(4000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
Thread wyplacacz = new Thread(new Runnable() { Thread wyplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
konto.wyplataCzekaj(100); konto.wyplataCzekaj(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo()); System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
try { try {
Thread.sleep(200); Thread.sleep(200);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
wplacacz.start(); wplacacz.start();
wyplacacz.start(); wyplacacz.start();
System.out.println("Wątki wystartowały"); System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć"); System.out.println("Naciśnij enter aby zakończyć");
try { try {
System.in.read(); System.in.read();
} catch (IOException e1) { } catch (IOException e1) {
} }
koniec = true; koniec = true;
try { try {
wplacacz.join(); wplacacz.join();
wyplacacz.join(); wyplacacz.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.err.println("INTERRUPTED"); System.err.println("INTERRUPTED");
} }
System.out.println("na końcu: " + konto); System.out.println("na końcu: " + konto);
} }
} }
package watki.gotowe.konta.v6_synchronizacja_na_zwyklych_obiektach; package watki.gotowe.konta.v6_synchronizacja_na_zwyklych_obiektach;
public class BrakSrodkow extends Exception { public class BrakSrodkow extends Exception {
private static final long serialVersionUID = 5262944731342409658L; private static final long serialVersionUID = 5262944731342409658L;
public BrakSrodkow() { public BrakSrodkow() {
super(); super();
} }
public BrakSrodkow(String message) { public BrakSrodkow(String message) {
super(message); super(message);
} }
} }
...@@ -11,90 +11,90 @@ import java.util.List; ...@@ -11,90 +11,90 @@ import java.util.List;
*/ */
class Konto { class Konto {
private final int numer; private final int numer;
private int saldo; private int saldo;
private Osoba wlasciciel; private Osoba wlasciciel;
private List<String> wnioski = new ArrayList<>(); private List<String> wnioski = new ArrayList<>();
// te obiekty istnieją tylko po to, aby wątki mogły "na nich czekać" // te obiekty istnieją tylko po to, aby wątki mogły "na nich czekać"
private Object ochronaSalda = new Object(); private Object ochronaSalda = new Object();
private Object ochronaWnioskow = new Object(); private Object ochronaWnioskow = new Object();
public Konto(int numer, int saldo, Osoba wlasciciel) { public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer; this.numer = numer;
this.saldo = saldo; this.saldo = saldo;
this.wlasciciel = wlasciciel; this.wlasciciel = wlasciciel;
} }
public String toString() { public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel; return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel;
} }
public void wplata(int kwota) { public void wplata(int kwota) {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
} }
synchronized(ochronaSalda) { synchronized(ochronaSalda) {
saldo += kwota; saldo += kwota;
ochronaSalda.notify(); ochronaSalda.notify();
} }
} }
public void wyplata(int kwota) throws BrakSrodkow { public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
} }
synchronized(ochronaSalda) { synchronized(ochronaSalda) {
if(kwota > saldo) { if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer); throw new BrakSrodkow("Brak środków na koncie nr " + numer);
} }
saldo -= kwota; saldo -= kwota;
} }
} }
public void wyplataCzekaj(int kwota) throws BrakSrodkow { public void wyplataCzekaj(int kwota) throws BrakSrodkow {
if(kwota < 0) { if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie"); throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
} }
try { try {
synchronized(ochronaSalda) { synchronized(ochronaSalda) {
while(kwota > saldo) { while(kwota > saldo) {
ochronaSalda.wait(); ochronaSalda.wait();
} }
saldo -= kwota; saldo -= kwota;
ochronaSalda.notify(); ochronaSalda.notify();
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
// Jeśli ktoś przerwie za pomocą interrupt(), tzn. "nie czekaj już, daj sobie spokój", wtedy rezygnuję z wykonania operacji biznesowej // Jeśli ktoś przerwie za pomocą interrupt(), tzn. "nie czekaj już, daj sobie spokój", wtedy rezygnuję z wykonania operacji biznesowej
} }
} }
public Osoba getWlasciciel() { public Osoba getWlasciciel() {
return wlasciciel; return wlasciciel;
} }
public void setWlasciciel(Osoba wlasciciel) { public void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel; this.wlasciciel = wlasciciel;
} }
public int getNumer() { public int getNumer() {
return numer; return numer;
} }
public int getSaldo() { public int getSaldo() {
synchronized(ochronaSalda) { synchronized(ochronaSalda) {
return saldo; return saldo;
} }
} }
public void zlozWniosekKredytowy(int suma) { public void zlozWniosekKredytowy(int suma) {
synchronized(ochronaWnioskow) { synchronized(ochronaWnioskow) {
wnioski.add("Wniosek o " + suma); wnioski.add("Wniosek o " + suma);
} }
} }
} }
...@@ -4,63 +4,63 @@ import java.time.LocalDate; ...@@ -4,63 +4,63 @@ import java.time.LocalDate;
import java.time.Period; import java.time.Period;
class Osoba { class Osoba {
private String imie, nazwisko; private String imie, nazwisko;
private LocalDate dataUrodzenia; private LocalDate dataUrodzenia;
public Osoba() { public Osoba() {
} }
Osoba(String imie, String nazwisko) { Osoba(String imie, String nazwisko) {
this.imie = imie; this.imie = imie;
this.nazwisko = nazwisko; this.nazwisko = nazwisko;
} }
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) { public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.setImie(imie); this.setImie(imie);
this.nazwisko = nazwisko; this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia; this.dataUrodzenia = dataUrodzenia;
} }
public Osoba(String imie, String nazwisko, String dataUrodzenia) { public Osoba(String imie, String nazwisko, String dataUrodzenia) {
// wywołanie innego konstruktora z tej samej klasy // wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, LocalDate.parse(dataUrodzenia)); this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
} }
public int obliczWiek() { public int obliczWiek() {
LocalDate dzisiaj = LocalDate.now(); LocalDate dzisiaj = LocalDate.now();
Period wiek = Period.between(dataUrodzenia, dzisiaj); Period wiek = Period.between(dataUrodzenia, dzisiaj);
return wiek.getYears(); return wiek.getYears();
} }
@Override @Override
public String toString() { public String toString() {
return imie + " " +nazwisko + " ur." + dataUrodzenia; return imie + " " +nazwisko + " ur." + dataUrodzenia;
} }
public String kimJestes() { public String kimJestes() {
return "Jestem osobą"; return "Jestem osobą";
} }
public String getImie() { public String getImie() {
return imie; return imie;
} }
public String getNazwisko() { public String getNazwisko() {
return nazwisko; return nazwisko;
} }
public LocalDate getDataUrodzenia() { public LocalDate getDataUrodzenia() {
return dataUrodzenia; return dataUrodzenia;
} }
public void setImie(String imie) { public void setImie(String imie) {
if(imie == null || imie.isEmpty()) { if(imie == null || imie.isEmpty()) {
throw new IllegalArgumentException("imię nie może być puste"); throw new IllegalArgumentException("imię nie może być puste");
} }
this.imie = imie; this.imie = imie;
} }
public void setNazwisko(String nazwisko) { public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko; this.nazwisko = nazwisko;
} }
} }
...@@ -4,45 +4,45 @@ import java.time.LocalDate; ...@@ -4,45 +4,45 @@ import java.time.LocalDate;
class Przeploty { class Przeploty {
public static void main(String[] args) { public static void main(String[] args) {
final int N = 100_000; final int N = 100_000;
final int KWOTA = 10; final int KWOTA = 10;
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now()); Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now());
Konto konto = new Konto(1, 1000_000, ala); Konto konto = new Konto(1, 1000_000, ala);
System.out.println(konto); System.out.println(konto);
Thread wplacacz = new Thread(() -> { Thread wplacacz = new Thread(() -> {
for(int i = 0 ; i < N; i++) { for(int i = 0 ; i < N; i++) {
konto.wplata(KWOTA); konto.wplata(KWOTA);
} }
}); });
Thread wyplacacz = new Thread(() -> { Thread wyplacacz = new Thread(() -> {
for(int i = 0; i < N; i++) { for(int i = 0; i < N; i++) {
try { try {
konto.wyplata(KWOTA); konto.wyplata(KWOTA);
} catch (BrakSrodkow e) { } catch (BrakSrodkow e) {
System.err.println(e.getMessage()); System.err.println(e.getMessage());
} }
} }
}); });
System.out.println("Uruchamiam wątki"); System.out.println("Uruchamiam wątki");
wplacacz.start(); wplacacz.start();
wyplacacz.start(); wyplacacz.start();
System.out.println("Czekam na zakończenie"); System.out.println("Czekam na zakończenie");
try { try {
wplacacz.join(); wplacacz.join();
wyplacacz.join(); wyplacacz.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
System.out.println("Wątki zakończone, konto na końcu:"); System.out.println("Wątki zakończone, konto na końcu:");
System.out.println(konto); System.out.println(konto);
} }
} }
...@@ -4,63 +4,63 @@ import java.io.IOException; ...@@ -4,63 +4,63 @@ import java.io.IOException;
class WyplacanieBezOczekiwania { class WyplacanieBezOczekiwania {
static volatile boolean koniec = false; static volatile boolean koniec = false;
public static void main(String[] args) { public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01"); final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala); final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto); System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() { Thread wplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
konto.wplata(1000); konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo()); System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try { try {
Thread.sleep(4000); Thread.sleep(4000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
Thread wyplacacz = new Thread(new Runnable() { Thread wyplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
try { try {
konto.wyplata(100); konto.wyplata(100);
} catch (BrakSrodkow e) { } catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW"); System.err.println("BRAK ŚRODKÓW");
} }
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo()); System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
try { try {
Thread.sleep(200); Thread.sleep(200);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
wplacacz.start(); wplacacz.start();
wyplacacz.start(); wyplacacz.start();
System.out.println("Wątki wystartowały"); System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć"); System.out.println("Naciśnij enter aby zakończyć");
try { try {
System.in.read(); System.in.read();
} catch (IOException e1) { } catch (IOException e1) {
} }
koniec = true; koniec = true;
try { try {
wplacacz.join(); wplacacz.join();
wyplacacz.join(); wyplacacz.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.err.println("INTERRUPTED"); System.err.println("INTERRUPTED");
} }
System.out.println("na końcu: " + konto); System.out.println("na końcu: " + konto);
} }
} }
...@@ -4,63 +4,63 @@ import java.io.IOException; ...@@ -4,63 +4,63 @@ import java.io.IOException;
class WyplacanieZOczekiwaniem { class WyplacanieZOczekiwaniem {
static volatile boolean koniec = false; static volatile boolean koniec = false;
public static void main(String[] args) { public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01"); final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala); final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto); System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() { Thread wplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
konto.wplata(1000); konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo()); System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try { try {
Thread.sleep(4000); Thread.sleep(4000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
Thread wyplacacz = new Thread(new Runnable() { Thread wyplacacz = new Thread(new Runnable() {
public void run() { public void run() {
while (!koniec) { while (!koniec) {
try { try {
konto.wyplataCzekaj(100); konto.wyplataCzekaj(100);
} catch (BrakSrodkow e) { } catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW"); System.err.println("BRAK ŚRODKÓW");
} }
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo()); System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
try { try {
Thread.sleep(200); Thread.sleep(200);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
}); });
wplacacz.start(); wplacacz.start();
wyplacacz.start(); wyplacacz.start();
System.out.println("Wątki wystartowały"); System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć"); System.out.println("Naciśnij enter aby zakończyć");
try { try {
System.in.read(); System.in.read();
} catch (IOException e1) { } catch (IOException e1) {
} }
koniec = true; koniec = true;
try { try {
wplacacz.join(); wplacacz.join();
wyplacacz.join(); wyplacacz.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.err.println("INTERRUPTED"); System.err.println("INTERRUPTED");
} }
System.out.println("na końcu: " + konto); System.out.println("na końcu: " + konto);
} }
} }
...@@ -6,86 +6,86 @@ import java.util.concurrent.ForkJoinTask; ...@@ -6,86 +6,86 @@ import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
public class ForkJoin1_SumArray { public class ForkJoin1_SumArray {
static class SumArray extends ForkJoinTask<Long> { static class SumArray extends ForkJoinTask<Long> {
private Long result; private Long result;
private byte[] array; private byte[] array;
private int from, to; private int from, to;
public SumArray(byte[] array, int from, int to) { public SumArray(byte[] array, int from, int to) {
this.array = array; this.array = array;
this.from = from; this.from = from;
this.to = to; this.to = to;
} }
@Override @Override
public Long getRawResult() { public Long getRawResult() {
return result; return result;
} }
@Override @Override
protected void setRawResult(Long value) { protected void setRawResult(Long value) {
this.result = value; this.result = value;
} }
@Override @Override
protected boolean exec() { protected boolean exec() {
if(to - from == 1) { if(to - from == 1) {
this.setRawResult(Long.valueOf(array[from])); this.setRawResult(Long.valueOf(array[from]));
} else { } else {
int middle = (from + to) / 2; int middle = (from + to) / 2;
SumArray left = new SumArray(array, from, middle); SumArray left = new SumArray(array, from, middle);
SumArray right = new SumArray(array, middle, to); SumArray right = new SumArray(array, middle, to);
left.fork(); left.fork();
right.fork(); right.fork();
try { try {
Long part1 = left.get(); Long part1 = left.get();
Long part2 = right.get(); Long part2 = right.get();
setRawResult(part1 + part2); setRawResult(part1 + part2);
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
e.printStackTrace(); e.printStackTrace();
setRawResult(0L); setRawResult(0L);
} }
} }
return true; return true;
} }
} }
public static void main(String[] args) { public static void main(String[] args) {
byte[] tab = new byte[160_000_000]; byte[] tab = new byte[160_000_000];
final ThreadLocalRandom random = ThreadLocalRandom.current(); final ThreadLocalRandom random = ThreadLocalRandom.current();
System.out.println("Losowanie..."); System.out.println("Losowanie...");
for(int i = 0; i < tab.length; i++) for(int i = 0; i < tab.length; i++)
tab[i] = (byte)random.nextInt(256); tab[i] = (byte)random.nextInt(256);
Long result; Long result;
System.out.println("\nLiczenie sekwencyjne:"); System.out.println("\nLiczenie sekwencyjne:");
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
result = sumaSekwencyjnie(tab); result = sumaSekwencyjnie(tab);
long stop = System.currentTimeMillis(); long stop = System.currentTimeMillis();
System.out.println("Result = " + result + " , czas = " + (stop - start)); System.out.println("Result = " + result + " , czas = " + (stop - start));
System.out.println("\nLiczenie fork/join:"); System.out.println("\nLiczenie fork/join:");
final ForkJoinPool pool = new ForkJoinPool(8); final ForkJoinPool pool = new ForkJoinPool(8);
SumArray task = new SumArray(tab, 0, tab.length); SumArray task = new SumArray(tab, 0, tab.length);
System.out.println("Start"); System.out.println("Start");
start = System.currentTimeMillis(); start = System.currentTimeMillis();
result = pool.invoke(task); result = pool.invoke(task);
stop = System.currentTimeMillis(); stop = System.currentTimeMillis();
System.out.println("Result = " + result + " , czas = " + (stop - start)); System.out.println("Result = " + result + " , czas = " + (stop - start));
} }
private static long sumaSekwencyjnie(byte[] tab, int from, int to) { private static long sumaSekwencyjnie(byte[] tab, int from, int to) {
long suma = 0; long suma = 0;
while(from < to) while(from < to)
suma += tab[from++]; suma += tab[from++];
return suma; return suma;
} }
private static long sumaSekwencyjnie(byte[] tab) { private static long sumaSekwencyjnie(byte[] tab) {
return sumaSekwencyjnie(tab, 0, tab.length); return sumaSekwencyjnie(tab, 0, tab.length);
} }
} }
...@@ -6,88 +6,88 @@ import java.util.concurrent.ForkJoinTask; ...@@ -6,88 +6,88 @@ import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
public class ForkJoin2_SumArray_Limit_Get { public class ForkJoin2_SumArray_Limit_Get {
static class SumArray extends ForkJoinTask<Long> { static class SumArray extends ForkJoinTask<Long> {
private Long result; private Long result;
private byte[] array; private byte[] array;
private int from, to; private int from, to;
public SumArray(byte[] array, int from, int to) { public SumArray(byte[] array, int from, int to) {
this.array = array; this.array = array;
this.from = from; this.from = from;
this.to = to; this.to = to;
} }
@Override @Override
public Long getRawResult() { public Long getRawResult() {
return result; return result;
} }
@Override @Override
protected void setRawResult(Long value) { protected void setRawResult(Long value) {
this.result = value; this.result = value;
} }
@Override @Override
protected boolean exec() { protected boolean exec() {
if(to - from <= 10_000_000) { if(to - from <= 10_000_000) {
Long x = sumaSekwencyjnie(array, from, to); Long x = sumaSekwencyjnie(array, from, to);
this.setRawResult(x); this.setRawResult(x);
} else { } else {
int middle = (from + to) / 2; int middle = (from + to) / 2;
SumArray left = new SumArray(array, from, middle); SumArray left = new SumArray(array, from, middle);
SumArray right = new SumArray(array, middle, to); SumArray right = new SumArray(array, middle, to);
left.fork(); left.fork();
right.fork(); right.fork();
try { try {
Long part1 = left.get(); Long part1 = left.get();
Long part2 = right.get(); Long part2 = right.get();
setRawResult(part1 + part2); setRawResult(part1 + part2);
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
e.printStackTrace(); e.printStackTrace();
setRawResult(0L); setRawResult(0L);
return false; return false;
} }
} }
return true; return true;
} }
} }
public static void main(String[] args) { public static void main(String[] args) {
byte[] tab = new byte[160_000_000]; byte[] tab = new byte[160_000_000];
final ThreadLocalRandom random = ThreadLocalRandom.current(); final ThreadLocalRandom random = ThreadLocalRandom.current();
System.out.println("Losowanie..."); System.out.println("Losowanie...");
for(int i = 0; i < tab.length; i++) for(int i = 0; i < tab.length; i++)
tab[i] = (byte)random.nextInt(256); tab[i] = (byte)random.nextInt(256);
Long result; Long result;
final ForkJoinPool pool = new ForkJoinPool(8); final ForkJoinPool pool = new ForkJoinPool(8);
System.out.println("\nLiczenie sekwencyjne:"); System.out.println("\nLiczenie sekwencyjne:");
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
result = sumaSekwencyjnie(tab); result = sumaSekwencyjnie(tab);
long stop = System.currentTimeMillis(); long stop = System.currentTimeMillis();
System.out.println("Result = " + result + " , czas = " + (stop - start)); System.out.println("Result = " + result + " , czas = " + (stop - start));
System.out.println("\nLiczenie fork/join:"); System.out.println("\nLiczenie fork/join:");
SumArray task = new SumArray(tab, 0, tab.length); SumArray task = new SumArray(tab, 0, tab.length);
System.out.println("Start"); System.out.println("Start");
start = System.currentTimeMillis(); start = System.currentTimeMillis();
result = pool.invoke(task); result = pool.invoke(task);
stop = System.currentTimeMillis(); stop = System.currentTimeMillis();
System.out.println("Result = " + result + " , czas = " + (stop - start)); System.out.println("Result = " + result + " , czas = " + (stop - start));
} }
private static Long sumaSekwencyjnie(byte[] tab, int from, int to) { private static Long sumaSekwencyjnie(byte[] tab, int from, int to) {
long suma = 0; long suma = 0;
while(from < to) while(from < to)
suma += tab[from++]; suma += tab[from++];
return suma; return suma;
} }
private static Long sumaSekwencyjnie(byte[] tab) { private static Long sumaSekwencyjnie(byte[] tab) {
return sumaSekwencyjnie(tab, 0, tab.length); return sumaSekwencyjnie(tab, 0, tab.length);
} }
} }
...@@ -5,85 +5,85 @@ import java.util.concurrent.ForkJoinTask; ...@@ -5,85 +5,85 @@ import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
public class ForkJoin3_SumArray_Limit_Join { public class ForkJoin3_SumArray_Limit_Join {
static class SumArray extends ForkJoinTask<Long> { static class SumArray extends ForkJoinTask<Long> {
private Long result; private Long result;
private byte[] array; private byte[] array;
private int from, to; private int from, to;
public SumArray(byte[] array, int from, int to) { public SumArray(byte[] array, int from, int to) {
this.array = array; this.array = array;
this.from = from; this.from = from;
this.to = to; this.to = to;
} }
@Override @Override
public Long getRawResult() { public Long getRawResult() {
return result; return result;
} }
@Override @Override
protected void setRawResult(Long value) { protected void setRawResult(Long value) {
this.result = value; this.result = value;
} }
@Override @Override
protected boolean exec() { protected boolean exec() {
if(to - from <= 10_000_000) { if(to - from <= 10_000_000) {
Long x = sumaSekwencyjnie(array, from, to); Long x = sumaSekwencyjnie(array, from, to);
this.setRawResult(x); this.setRawResult(x);
} else { } else {
int middle = (from + to) / 2; int middle = (from + to) / 2;
SumArray left = new SumArray(array, from, middle); SumArray left = new SumArray(array, from, middle);
SumArray right = new SumArray(array, middle, to); SumArray right = new SumArray(array, middle, to);
left.fork(); left.fork();
right.fork(); right.fork();
Long part1 = left.join(); Long part1 = left.join();
Long part2 = right.join(); Long part2 = right.join();
setRawResult(part1 + part2); setRawResult(part1 + part2);
// join nie deklaruje żadnych wyjątków, a get deklaruje Interrupted i ExecutionException // join nie deklaruje żadnych wyjątków, a get deklaruje Interrupted i ExecutionException
} }
return true; return true;
} }
} }
public static void main(String[] args) { public static void main(String[] args) {
byte[] tab = new byte[160_000_000]; byte[] tab = new byte[160_000_000];
final ThreadLocalRandom random = ThreadLocalRandom.current(); final ThreadLocalRandom random = ThreadLocalRandom.current();
System.out.println("Losowanie..."); System.out.println("Losowanie...");
for(int i = 0; i < tab.length; i++) for(int i = 0; i < tab.length; i++)
tab[i] = (byte)random.nextInt(256); tab[i] = (byte)random.nextInt(256);
Long result; Long result;
final ForkJoinPool pool = new ForkJoinPool(8); final ForkJoinPool pool = new ForkJoinPool(8);
System.out.println("\nLiczenie sekwencyjne:"); System.out.println("\nLiczenie sekwencyjne:");
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
result = sumaSekwencyjnie(tab); result = sumaSekwencyjnie(tab);
long stop = System.currentTimeMillis(); long stop = System.currentTimeMillis();
System.out.println("Result = " + result + " , czas = " + (stop - start)); System.out.println("Result = " + result + " , czas = " + (stop - start));
System.out.println("\nLiczenie fork/join:"); System.out.println("\nLiczenie fork/join:");
SumArray task = new SumArray(tab, 0, tab.length); SumArray task = new SumArray(tab, 0, tab.length);
System.out.println("Start"); System.out.println("Start");
start = System.currentTimeMillis(); start = System.currentTimeMillis();
result = pool.invoke(task); result = pool.invoke(task);
stop = System.currentTimeMillis(); stop = System.currentTimeMillis();
System.out.println("Result = " + result + " , czas = " + (stop - start)); System.out.println("Result = " + result + " , czas = " + (stop - start));
} }
private static Long sumaSekwencyjnie(byte[] tab, int from, int to) { private static Long sumaSekwencyjnie(byte[] tab, int from, int to) {
long suma = 0; long suma = 0;
while(from < to) while(from < to)
suma += tab[from++]; suma += tab[from++];
return suma; return suma;
} }
private static Long sumaSekwencyjnie(byte[] tab) { private static Long sumaSekwencyjnie(byte[] tab) {
return sumaSekwencyjnie(tab, 0, tab.length); return sumaSekwencyjnie(tab, 0, tab.length);
} }
} }
...@@ -5,72 +5,72 @@ import java.util.concurrent.RecursiveTask; ...@@ -5,72 +5,72 @@ import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
public class ForkJoin4_SumArray_RecursiveTask { public class ForkJoin4_SumArray_RecursiveTask {
// Wersja, gdzie korzystamy z klasy RecursiveTask (podklasa ForkJoinTask), // Wersja, gdzie korzystamy z klasy RecursiveTask (podklasa ForkJoinTask),
// która realizuje dokładnie taki schemat, o jaki nam chodzi: zadania zwracające wynik, które da się dzielić na mniejsze. // która realizuje dokładnie taki schemat, o jaki nam chodzi: zadania zwracające wynik, które da się dzielić na mniejsze.
static class SumArray extends RecursiveTask<Long> { static class SumArray extends RecursiveTask<Long> {
private byte[] array; private byte[] array;
private int from, to; private int from, to;
public SumArray(byte[] array, int from, int to) { public SumArray(byte[] array, int from, int to) {
this.array = array; this.array = array;
this.from = from; this.from = from;
this.to = to; this.to = to;
} }
@Override @Override
protected Long compute() { protected Long compute() {
if(to - from <= 10_000_000) { if(to - from <= 10_000_000) {
Long x = sumaSekwencyjnie(array, from, to); Long x = sumaSekwencyjnie(array, from, to);
return x; return x;
} else { } else {
int middle = (from + to) / 2; int middle = (from + to) / 2;
SumArray left = new SumArray(array, from, middle); SumArray left = new SumArray(array, from, middle);
SumArray right = new SumArray(array, middle, to); SumArray right = new SumArray(array, middle, to);
left.fork(); left.fork();
right.fork(); right.fork();
Long part1 = left.join(); Long part1 = left.join();
Long part2 = right.join(); Long part2 = right.join();
return part1 + part2; return part1 + part2;
} }
} }
} }
public static void main(String[] args) { public static void main(String[] args) {
byte[] tab = new byte[160_000_000]; byte[] tab = new byte[160_000_000];
final ThreadLocalRandom random = ThreadLocalRandom.current(); final ThreadLocalRandom random = ThreadLocalRandom.current();
System.out.println("Losowanie..."); System.out.println("Losowanie...");
for(int i = 0; i < tab.length; i++) for(int i = 0; i < tab.length; i++)
tab[i] = (byte)random.nextInt(256); tab[i] = (byte)random.nextInt(256);
Long result; Long result;
final ForkJoinPool pool = new ForkJoinPool(8); final ForkJoinPool pool = new ForkJoinPool(8);
System.out.println("\nLiczenie sekwencyjne:"); System.out.println("\nLiczenie sekwencyjne:");
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
result = sumaSekwencyjnie(tab); result = sumaSekwencyjnie(tab);
long stop = System.currentTimeMillis(); long stop = System.currentTimeMillis();
System.out.println("Result = " + result + " , czas = " + (stop - start)); System.out.println("Result = " + result + " , czas = " + (stop - start));
System.out.println("\nLiczenie fork/join:"); System.out.println("\nLiczenie fork/join:");
SumArray task = new SumArray(tab, 0, tab.length); SumArray task = new SumArray(tab, 0, tab.length);
System.out.println("Start"); System.out.println("Start");
start = System.currentTimeMillis(); start = System.currentTimeMillis();
result = pool.invoke(task); result = pool.invoke(task);
stop = System.currentTimeMillis(); stop = System.currentTimeMillis();
System.out.println("Result = " + result + " , czas = " + (stop - start)); System.out.println("Result = " + result + " , czas = " + (stop - start));
} }
private static Long sumaSekwencyjnie(byte[] tab, int from, int to) { private static Long sumaSekwencyjnie(byte[] tab, int from, int to) {
long suma = 0; long suma = 0;
while(from < to) while(from < to)
suma += tab[from++]; suma += tab[from++];
return suma; return suma;
} }
private static Long sumaSekwencyjnie(byte[] tab) { private static Long sumaSekwencyjnie(byte[] tab) {
return sumaSekwencyjnie(tab, 0, tab.length); return sumaSekwencyjnie(tab, 0, tab.length);
} }
} }
...@@ -6,60 +6,60 @@ import java.util.concurrent.RecursiveAction; ...@@ -6,60 +6,60 @@ import java.util.concurrent.RecursiveAction;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
/* Przykład z dokumentacji klasy RecursiveAction - sortowanie tablicy */ /* Przykład z dokumentacji klasy RecursiveAction - sortowanie tablicy */
public class ForkJoin5_SortArray_RecursiveAction { public class ForkJoin5_SortArray_RecursiveAction {
static class SortTask extends RecursiveAction { static class SortTask extends RecursiveAction {
final long[] array; final long[] array;
final int lo, hi; final int lo, hi;
SortTask(long[] array, int lo, int hi) { SortTask(long[] array, int lo, int hi) {
this.array = array; this.array = array;
this.lo = lo; this.lo = lo;
this.hi = hi; this.hi = hi;
} }
SortTask(long[] array) { SortTask(long[] array) {
this(array, 0, array.length); this(array, 0, array.length);
} }
protected void compute() { protected void compute() {
if (hi - lo < THRESHOLD) if (hi - lo < THRESHOLD)
sortSequentially(lo, hi); sortSequentially(lo, hi);
else { else {
int mid = (lo + hi) >>> 1; int mid = (lo + hi) >>> 1;
invokeAll(new SortTask(array, lo, mid), new SortTask(array, mid, hi)); invokeAll(new SortTask(array, lo, mid), new SortTask(array, mid, hi));
merge(lo, mid, hi); merge(lo, mid, hi);
} }
} }
// implementation details follow: // implementation details follow:
static final int THRESHOLD = 1000; static final int THRESHOLD = 1000;
void sortSequentially(int lo, int hi) { void sortSequentially(int lo, int hi) {
Arrays.sort(array, lo, hi); Arrays.sort(array, lo, hi);
} }
void merge(int lo, int mid, int hi) { void merge(int lo, int mid, int hi) {
long[] buf = Arrays.copyOfRange(array, lo, mid); long[] buf = Arrays.copyOfRange(array, lo, mid);
for (int i = 0, j = lo, k = mid; i < buf.length; j++) for (int i = 0, j = lo, k = mid; i < buf.length; j++)
array[j] = (k == hi || buf[i] < array[k]) ? buf[i++] : array[k++]; array[j] = (k == hi || buf[i] < array[k]) ? buf[i++] : array[k++];
} }
} }
public static void main(String[] args) { public static void main(String[] args) {
long[] tab = new long[80_000_000]; long[] tab = new long[80_000_000];
final ThreadLocalRandom random = ThreadLocalRandom.current(); final ThreadLocalRandom random = ThreadLocalRandom.current();
System.out.println("Losowanie..."); System.out.println("Losowanie...");
for(int i = 0; i < tab.length; i++) for(int i = 0; i < tab.length; i++)
tab[i] = random.nextInt(256); tab[i] = random.nextInt(256);
final ForkJoinPool pool = new ForkJoinPool(8); final ForkJoinPool pool = new ForkJoinPool(8);
SortTask task = new SortTask(tab); SortTask task = new SortTask(tab);
System.out.println("Start"); System.out.println("Start");
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
pool.invoke(task); pool.invoke(task);
long stop = System.currentTimeMillis(); long stop = System.currentTimeMillis();
System.out.println("OK, czas = " + (stop - start)); System.out.println("OK, czas = " + (stop - start));
} }
} }
...@@ -3,56 +3,55 @@ package watki.gotowe.pule; ...@@ -3,56 +3,55 @@ package watki.gotowe.pule;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class PuleWatkow { public class PuleWatkow {
public static void main(String[] args) throws InterruptedException, ExecutionException { public static void main(String[] args) throws InterruptedException, ExecutionException {
final int N = 100; // liczba procedur do wykonania final int N = 100; // liczba procedur do wykonania
// ExecutorService pool = Executors.newSingleThreadExecutor(); // ExecutorService pool = Executors.newSingleThreadExecutor();
ExecutorService pool = Executors.newFixedThreadPool(20); ExecutorService pool = Executors.newFixedThreadPool(20);
// ExecutorService pool = Executors.newCachedThreadPool(); // tworzy wątek, gdy tylko brakuje robotników // ExecutorService pool = Executors.newCachedThreadPool(); // tworzy wątek, gdy tylko brakuje robotników
// ExecutorService pool = Executors.newWorkStealingPool(); // od Javy 8 - stara się wykorzystać wszystkie procesory // ExecutorService pool = Executors.newWorkStealingPool(); // od Javy 8 - stara się wykorzystać wszystkie procesory
// ExecutorService pool = Executors.newWorkStealingPool(2); // wersja z ograniczeniem współbieżności do pewnego poziomu // ExecutorService pool = Executors.newWorkStealingPool(2); // wersja z ograniczeniem współbieżności do pewnego poziomu
// ScheduledExecutorService pool = Executors.newScheduledThreadPool(20); // pozwala planować zadania na przyszłość // ScheduledExecutorService pool = Executors.newScheduledThreadPool(20); // pozwala planować zadania na przyszłość
Procedura zadanie = new Procedura(); Procedura zadanie = new Procedura();
System.out.println("Zaczynam zlecać..."); System.out.println("Zaczynam zlecać...");
for(int i = 0; i < N; i++) { for(int i = 0; i < N; i++) {
pool.submit(zadanie); pool.submit(zadanie);
// pool.execute(zadanie); // pool.execute(zadanie);
// pool.schedule(zadanie, 2, TimeUnit.SECONDS); // pool.schedule(zadanie, 2, TimeUnit.SECONDS);
try { try {
Thread.sleep(1); Thread.sleep(1);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
System.out.println("Zlecilem wykonanie"); System.out.println("Zlecilem wykonanie");
pool.shutdown(); pool.shutdown();
//pool.shutdownNow(); //pool.shutdownNow();
System.out.println("Po shutdown"); System.out.println("Po shutdown");
//pool.submit(() -> {}); //pool.submit(() -> {});
try { try {
pool.awaitTermination(1, TimeUnit.DAYS); pool.awaitTermination(1, TimeUnit.DAYS);
System.out.println("Zakończyły się"); System.out.println("Zakończyły się");
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
System.out.println("Koniec main"); System.out.println("Koniec main");
} }
private static class Procedura implements Runnable { private static class Procedura implements Runnable {
public void run() { public void run() {
long id = Thread.currentThread().getId(); long id = Thread.currentThread().getId();
System.out.printf("Hej, tu watek %d%n", id); System.out.printf("Hej, tu watek %d%n", id);
try { try {
Thread.sleep(10); Thread.sleep(10);
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.out.println("interrupt w " + id); System.out.println("interrupt w " + id);
} }
} }
} }
} }
package watki.gotowe.pule; package watki.gotowe.pule;
import java.util.concurrent.Callable; import java.util.concurrent.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class PuleWatkowCallable { public class PuleWatkowCallable {
public static void main(String[] args) throws InterruptedException, ExecutionException { public static void main(String[] args) throws InterruptedException, ExecutionException {
final int N = 10; // liczba procedur do wykonania final int N = 10; // liczba procedur do wykonania
final int M = 2; // liczba watkow w puli final int M = 2; // liczba watkow w puli
ExecutorService pool = Executors.newFixedThreadPool(M); ExecutorService pool = Executors.newFixedThreadPool(M);
Future<String> gfuture = null; Future<String> gfuture = null;
Procedura proc = new Procedura(); Procedura proc = new Procedura();
for(int i = 0; i < N; i++) { for(int i = 0; i < N; i++) {
Future<String> future = pool.submit(proc); Future<String> future = pool.submit(proc);
// System.out.println(future.isDone()); // System.out.println(future.isDone());
gfuture = future; gfuture = future;
} }
System.out.println("Zlecilem wykonanie"); System.out.println("Zlecilem wykonanie");
pool.shutdown(); pool.shutdown();
System.out.println("Po shutdown"); System.out.println("Po shutdown");
System.out.println(gfuture.isDone()); System.out.println(gfuture.isDone());
String wynik = gfuture.get(); // to powoduje oczekiwanie na zakończenie zadania String wynik = gfuture.get(); // to powoduje oczekiwanie na zakończenie zadania
System.out.println(gfuture.isDone() + wynik); System.out.println(gfuture.isDone() + wynik);
//pool.shutdownNow(); //pool.shutdownNow();
pool.awaitTermination(1, TimeUnit.DAYS); pool.awaitTermination(1, TimeUnit.DAYS);
System.out.println("Zakończyły się"); System.out.println("Zakończyły się");
System.out.println(gfuture.isDone()); System.out.println(gfuture.isDone());
} }
private static class Procedura implements Callable<String> { private static class Procedura implements Callable<String> {
@Override @Override
public String call() throws Exception { public String call() throws Exception {
System.out.printf("Hej, tu watek %d%n", Thread.currentThread().getId()); System.out.printf("Hej, tu watek %d%n", Thread.currentThread().getId());
try { try {
Thread.sleep(20); Thread.sleep(20);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
return " Wynik, wypisał wątek nr " + Thread.currentThread().getId(); return " Wynik, wypisał wątek nr " + Thread.currentThread().getId();
} }
} }
} }
...@@ -3,90 +3,90 @@ package watki.gotowe.rwlock; ...@@ -3,90 +3,90 @@ package watki.gotowe.rwlock;
import java.util.Random; import java.util.Random;
public class CzytelnicyPisarze_BezSynchronizacji { public class CzytelnicyPisarze_BezSynchronizacji {
private int[] t = new int[1000]; private int[] t = new int[1000];
private volatile boolean jeszcze = true; private volatile boolean jeszcze = true;
public static void main(String[] args) { public static void main(String[] args) {
new CzytelnicyPisarze_BezSynchronizacji().dzialaj(); new CzytelnicyPisarze_BezSynchronizacji().dzialaj();
} }
private void dzialaj() { private void dzialaj() {
System.out.println("Losuję liczby do tablicy"); System.out.println("Losuję liczby do tablicy");
Random random = new Random(); Random random = new Random();
for(int i=0; i<t.length; i++) { for(int i=0; i<t.length; i++) {
t[i] = random.nextInt(1000); t[i] = random.nextInt(1000);
} }
int suma = 0; int suma = 0;
for(int x : t) { for(int x : t) {
suma += x; suma += x;
} }
System.out.println("Suma na początku = " + suma); System.out.println("Suma na początku = " + suma);
System.out.println("Uruchamiam wątki"); System.out.println("Uruchamiam wątki");
Thread c1 = new Thread(new Czytelnik()); Thread c1 = new Thread(new Czytelnik());
Thread c2 = new Thread(new Czytelnik()); Thread c2 = new Thread(new Czytelnik());
Thread z1 = new Thread(new Zamieniacz()); Thread z1 = new Thread(new Zamieniacz());
Thread z2 = new Thread(new Zamieniacz()); Thread z2 = new Thread(new Zamieniacz());
c1.start(); c1.start();
c2.start(); c2.start();
z1.start(); z1.start();
z2.start(); z2.start();
System.out.println("Jadą"); System.out.println("Jadą");
try { try {
Thread.sleep(7000); Thread.sleep(7000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
jeszcze = false; jeszcze = false;
System.out.println("Koniec"); System.out.println("Koniec");
try { try {
c1.join(); c1.join();
c2.join(); c2.join();
z1.join(); z1.join();
z2.join(); z2.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
suma = 0; suma = 0;
for(int x : t) { for(int x : t) {
suma += x; suma += x;
} }
System.out.println("Suma na końcu = " + suma); System.out.println("Suma na końcu = " + suma);
} }
private class Zamieniacz implements Runnable { private class Zamieniacz implements Runnable {
public void run() { public void run() {
Random random = new Random(); Random random = new Random();
while(jeszcze) { while(jeszcze) {
int i = random.nextInt(t.length); int i = random.nextInt(t.length);
int j = random.nextInt(t.length); int j = random.nextInt(t.length);
// swap // swap
int x = t[i]; int x = t[i];
t[i] = t[j]; t[i] = t[j];
t[j] = x; t[j] = x;
} }
} }
} }
private class Czytelnik implements Runnable { private class Czytelnik implements Runnable {
public void run() { public void run() {
while(jeszcze) { while(jeszcze) {
int suma = 0; int suma = 0;
for(int x : t) { for(int x : t) {
suma += x; suma += x;
} }
System.out.println("Suma = " + suma); System.out.println("Suma = " + suma);
try { try {
Thread.sleep(500); Thread.sleep(500);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
} }
} }
...@@ -2,106 +2,104 @@ package watki.gotowe.rwlock; ...@@ -2,106 +2,104 @@ package watki.gotowe.rwlock;
import java.util.Random; import java.util.Random;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class CzytelnicyPisarze_Lock { public class CzytelnicyPisarze_Lock {
private Lock lock = new ReentrantLock(); private Lock lock = new ReentrantLock();
private int[] t = new int[1000]; private int[] t = new int[1000];
private volatile boolean jeszcze = true; private volatile boolean jeszcze = true;
public static void main(String[] args) { public static void main(String[] args) {
new CzytelnicyPisarze_Lock().dzialaj(); new CzytelnicyPisarze_Lock().dzialaj();
} }
private void dzialaj() { private void dzialaj() {
System.out.println("Losuję liczby do tablicy"); System.out.println("Losuję liczby do tablicy");
Random random = new Random(); Random random = new Random();
for(int i=0; i<t.length; i++) { for(int i=0; i<t.length; i++) {
t[i] = random.nextInt(1000); t[i] = random.nextInt(1000);
} }
int suma = 0; int suma = 0;
for(int x : t) { for(int x : t) {
suma += x; suma += x;
} }
System.out.println("Suma na początku = " + suma); System.out.println("Suma na początku = " + suma);
System.out.println("Uruchamiam wątki"); System.out.println("Uruchamiam wątki");
Thread c1 = new Thread(new Czytelnik()); Thread c1 = new Thread(new Czytelnik());
Thread c2 = new Thread(new Czytelnik()); Thread c2 = new Thread(new Czytelnik());
Thread z1 = new Thread(new Zamieniacz()); Thread z1 = new Thread(new Zamieniacz());
Thread z2 = new Thread(new Zamieniacz()); Thread z2 = new Thread(new Zamieniacz());
c1.start(); c1.start();
c2.start(); c2.start();
z1.start(); z1.start();
z2.start(); z2.start();
System.out.println("Jadą"); System.out.println("Jadą");
try { try {
Thread.sleep(7000); Thread.sleep(7000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
jeszcze = false; jeszcze = false;
System.out.println("Koniec"); System.out.println("Koniec");
try { try {
c1.join(); c1.join();
c2.join(); c2.join();
z1.join(); z1.join();
z2.join(); z2.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
suma = 0; suma = 0;
for(int x : t) { for(int x : t) {
suma += x; suma += x;
} }
System.out.println("Suma na końcu = " + suma); System.out.println("Suma na końcu = " + suma);
} }
private class Zamieniacz implements Runnable { private class Zamieniacz implements Runnable {
public void run() { public void run() {
Random random = new Random(); Random random = new Random();
while(jeszcze) { while(jeszcze) {
int i = random.nextInt(t.length); int i = random.nextInt(t.length);
int j = random.nextInt(t.length); int j = random.nextInt(t.length);
// swap // swap
lock.lock(); lock.lock();
try { try {
int x = t[i]; int x = t[i];
t[i] = t[j]; t[i] = t[j];
t[j] = x; t[j] = x;
} finally { } finally {
lock.unlock(); lock.unlock();
} }
} }
} }
} }
private class Czytelnik implements Runnable { private class Czytelnik implements Runnable {
public void run() { public void run() {
while(jeszcze) { while(jeszcze) {
int suma = 0; int suma = 0;
lock.lock(); lock.lock();
for(int x : t) { for(int x : t) {
suma += x; suma += x;
// try { // try {
// Thread.sleep(1); // Thread.sleep(1);
// } catch (InterruptedException e) { // } catch (InterruptedException e) {
// } // }
} }
lock.unlock(); lock.unlock();
System.out.println("Suma = " + suma); System.out.println("Suma = " + suma);
try { try {
Thread.sleep(500); Thread.sleep(500);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
} }
} }
...@@ -5,99 +5,99 @@ import java.util.concurrent.locks.ReadWriteLock; ...@@ -5,99 +5,99 @@ import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
public class CzytelnicyPisarze_RWLock { public class CzytelnicyPisarze_RWLock {
private ReadWriteLock rw = new ReentrantReadWriteLock(true); private ReadWriteLock rw = new ReentrantReadWriteLock(true);
private int[] t = new int[1000]; private int[] t = new int[1000];
private volatile boolean jeszcze = true; private volatile boolean jeszcze = true;
public static void main(String[] args) { public static void main(String[] args) {
new CzytelnicyPisarze_RWLock().dzialaj(); new CzytelnicyPisarze_RWLock().dzialaj();
} }
private void dzialaj() { private void dzialaj() {
System.out.println("Losuję liczby do tablicy"); System.out.println("Losuję liczby do tablicy");
Random random = new Random(); Random random = new Random();
for(int i=0; i<t.length; i++) { for(int i=0; i<t.length; i++) {
t[i] = random.nextInt(1000); t[i] = random.nextInt(1000);
} }
int suma = 0; int suma = 0;
for(int x : t) { for(int x : t) {
suma += x; suma += x;
} }
System.out.println("Suma na początku = " + suma); System.out.println("Suma na początku = " + suma);
System.out.println("Uruchamiam wątki"); System.out.println("Uruchamiam wątki");
Thread c1 = new Thread(new Czytelnik()); Thread c1 = new Thread(new Czytelnik());
Thread c2 = new Thread(new Czytelnik()); Thread c2 = new Thread(new Czytelnik());
Thread z1 = new Thread(new Zamieniacz()); Thread z1 = new Thread(new Zamieniacz());
Thread z2 = new Thread(new Zamieniacz()); Thread z2 = new Thread(new Zamieniacz());
c1.start(); c1.start();
c2.start(); c2.start();
z1.start(); z1.start();
z2.start(); z2.start();
System.out.println("Jadą"); System.out.println("Jadą");
try { try {
Thread.sleep(7000); Thread.sleep(7000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
jeszcze = false; jeszcze = false;
System.out.println("Koniec"); System.out.println("Koniec");
try { try {
c1.join(); c1.join();
c2.join(); c2.join();
z1.join(); z1.join();
z2.join(); z2.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
suma = 0; suma = 0;
for(int x : t) { for(int x : t) {
suma += x; suma += x;
} }
System.out.println("Suma na końcu = " + suma); System.out.println("Suma na końcu = " + suma);
} }
private class Zamieniacz implements Runnable { private class Zamieniacz implements Runnable {
public void run() { public void run() {
Random random = new Random(); Random random = new Random();
while(jeszcze) { while(jeszcze) {
int i = random.nextInt(t.length); int i = random.nextInt(t.length);
int j = random.nextInt(t.length); int j = random.nextInt(t.length);
// swap // swap
rw.writeLock().lock(); rw.writeLock().lock();
int x = t[i]; int x = t[i];
t[i] = t[j]; t[i] = t[j];
t[j] = x; t[j] = x;
rw.writeLock().unlock(); rw.writeLock().unlock();
} }
} }
} }
private class Czytelnik implements Runnable { private class Czytelnik implements Runnable {
public void run() { public void run() {
while(jeszcze) { while(jeszcze) {
int suma = 0; int suma = 0;
rw.readLock().lock(); rw.readLock().lock();
for(int x : t) { for(int x : t) {
suma += x; suma += x;
// try { // try {
// Thread.sleep(1); // Thread.sleep(1);
// } catch (InterruptedException e) { // } catch (InterruptedException e) {
// } // }
} }
rw.readLock().unlock(); rw.readLock().unlock();
System.out.println("Suma = " + suma); System.out.println("Suma = " + suma);
try { try {
Thread.sleep(500); Thread.sleep(500);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
} }
} }
...@@ -4,86 +4,86 @@ import java.util.concurrent.atomic.AtomicLongArray; ...@@ -4,86 +4,86 @@ import java.util.concurrent.atomic.AtomicLongArray;
import java.util.concurrent.atomic.AtomicReferenceArray; import java.util.concurrent.atomic.AtomicReferenceArray;
public class Priorytety { public class Priorytety {
private final int N; private final int N;
private final int T; private final int T;
private volatile boolean koniec = false; private volatile boolean koniec = false;
private final AtomicLongArray tablica; private final AtomicLongArray tablica;
private final AtomicReferenceArray<Thread> watki; private final AtomicReferenceArray<Thread> watki;
public Priorytety(int n, int t) { public Priorytety(int n, int t) {
this.N = n; this.N = n;
this.T = t; this.T = t;
this.tablica = new AtomicLongArray(n); this.tablica = new AtomicLongArray(n);
this.watki = new AtomicReferenceArray<>(n); this.watki = new AtomicReferenceArray<>(n);
} }
private class Robotnik implements Runnable { private class Robotnik implements Runnable {
private final int numer; private final int numer;
Robotnik(int numer) { Robotnik(int numer) {
this.numer = numer; this.numer = numer;
} }
public void run() { public void run() {
while(!koniec) { while(!koniec) {
tablica.incrementAndGet(numer); tablica.incrementAndGet(numer);
} }
} }
} }
private void run() { private void run() {
final int polowa = N / 2; final int polowa = N / 2;
for(int i = 0; i < N; i++) { for(int i = 0; i < N; i++) {
Thread th = new Thread(new Robotnik(i)); Thread th = new Thread(new Robotnik(i));
if(i < polowa) { if(i < polowa) {
th.setPriority(Thread.MAX_PRIORITY); th.setPriority(Thread.MAX_PRIORITY);
} else { } else {
th.setPriority(Thread.MIN_PRIORITY); th.setPriority(Thread.MIN_PRIORITY);
} }
watki.set(i, th); watki.set(i, th);
} }
for(int i = 0; i < N; i++) { for(int i = 0; i < N; i++) {
watki.get(i).start(); watki.get(i).start();
} }
try { try {
Thread.sleep(1000 * T); Thread.sleep(1000 * T);
koniec = true; koniec = true;
for(int i = 0; i < N; i++) { for(int i = 0; i < N; i++) {
watki.get(i).join(); watki.get(i).join();
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.err.println(e); System.err.println(e);
} }
for(int i = 0; i < N; i++) { for(int i = 0; i < N; i++) {
if(i == polowa) { if(i == polowa) {
System.out.println("================================"); System.out.println("================================");
} }
long razy = tablica.get(i); long razy = tablica.get(i);
System.out.printf("%2d : %15d razy\n", i, razy); System.out.printf("%2d : %15d razy\n", i, razy);
} }
} }
public static void main(String[] args) { public static void main(String[] args) {
// domyślne wartości parametrów: ilość wątków, czas trwania testu // domyślne wartości parametrów: ilość wątków, czas trwania testu
int N = 32; int N = 32;
int T = 10; int T = 10;
// inne można przekazać w cmd-line // inne można przekazać w cmd-line
if(args.length >= 1) { if(args.length >= 1) {
N = Integer.parseInt(args[0]); N = Integer.parseInt(args[0]);
} }
if(args.length >= 2) { if(args.length >= 2) {
T = Integer.parseInt(args[1]); T = Integer.parseInt(args[1]);
} }
System.out.printf("Startujemy %d wątków, czekaj %d sekund...\n", N, T); System.out.printf("Startujemy %d wątków, czekaj %d sekund...\n", N, T);
new Priorytety(N, T).run(); new Priorytety(N, T).run();
System.out.println("Koniec"); System.out.println("Koniec");
} }
} }
...@@ -4,37 +4,36 @@ import java.io.IOException; ...@@ -4,37 +4,36 @@ import java.io.IOException;
public class Przerwanie { public class Przerwanie {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("main: początek programu"); System.out.println("main: początek programu");
System.out.println("Mój obiekt Thread: " + Thread.currentThread()); System.out.println("Mój obiekt Thread: " + Thread.currentThread());
System.out.println("Moje id: " + Thread.currentThread().getId()); System.out.println("Moje id: " + Thread.currentThread().getId());
Thread th = new Thread(() -> { Thread th = new Thread(() -> {
System.out.println("Start"); System.out.println("Start");
try { try {
Thread.sleep(5000); Thread.sleep(5000);
System.out.println("sleep normalnie zakończony"); System.out.println("sleep normalnie zakończony");
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.out.println("sleep przerwany " + e); System.out.println("sleep przerwany " + e);
} }
System.out.println("interrupted() ? " + Thread.interrupted()); System.out.println("interrupted() ? " + Thread.interrupted());
System.out.println("Koniec"); System.out.println("Koniec");
}); });
System.out.println("main: robię th.start()"); System.out.println("main: robię th.start()");
th.start(); th.start();
System.out.println("Wystartowałem wątek. Naciśnij enter, aby przerwać."); System.out.println("Wystartowałem wątek. Naciśnij enter, aby przerwać.");
try { try {
System.in.read(); System.in.read();
// czekamy na ENTER i gdy zostanie naciśnięty, wywołamy interrupt na wątku // czekamy na ENTER i gdy zostanie naciśnięty, wywołamy interrupt na wątku
th.interrupt(); th.interrupt();
} catch (IOException e) {
} catch (IOException e) { e.printStackTrace();
e.printStackTrace(); };
};
System.out.println("Koniec main");
System.out.println("Koniec main"); }
}
} }
...@@ -2,11 +2,11 @@ package watki.gotowe.tworzenie; ...@@ -2,11 +2,11 @@ package watki.gotowe.tworzenie;
public class TworzeniePustegoWatku { public class TworzeniePustegoWatku {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("początek main"); System.out.println("początek main");
Thread th = new Thread(); Thread th = new Thread();
th.start(); th.start();
System.out.println("koniec main"); System.out.println("koniec main");
} }
} }
package watki.gotowe.tworzenie; package watki.gotowe.tworzenie;
public class TworzenieWatkow { public class TworzenieWatkow {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("Początek main, id wątku = " + Thread.currentThread().getId()); System.out.println("Początek main, id wątku = " + Thread.currentThread().getId());
// Jak tworzyć nowe wątki? // Jak tworzyć nowe wątki?
// 1) dziedziczenie z klasy Thread: // 1) dziedziczenie z klasy Thread:
class Watek0 extends Thread { class Watek0 extends Thread {
} }
class Watek1 extends Thread { class Watek1 extends Thread {
// nadpisując metodę run podajemy treść wątku - instrukcje, które będzie on wykonywał // nadpisując metodę run podajemy treść wątku - instrukcje, które będzie on wykonywał
@Override @Override
public void run() { public void run() {
System.out.println("Watek1 początek, id = " + Thread.currentThread().getId()); System.out.println("Watek1 początek, id = " + Thread.currentThread().getId());
for(int i = 1; i <= 10; i++) { for(int i = 1; i <= 10; i++) {
System.out.println("Watek1 działa, id = " + Thread.currentThread().getId() + ", i = " + i); System.out.println("Watek1 działa, id = " + Thread.currentThread().getId() + ", i = " + i);
} }
System.out.println("Watek1 koniec, id = " + Thread.currentThread().getId()); System.out.println("Watek1 koniec, id = " + Thread.currentThread().getId());
} }
} }
Watek1 watek1a = new Watek1(); Watek1 watek1a = new Watek1();
// wątek jeszcze nie wystartował // wątek jeszcze nie wystartował
// aby wątek zaczął działać, należy wywołać jego metodę // aby wątek zaczął działać, należy wywołać jego metodę
watek1a.start(); watek1a.start();
// gdybym wpisał watek1a.run(), to treść run też by się wykonała, // gdybym wpisał watek1a.run(), to treść run też by się wykonała,
// ale w jednym wątku main ("synchronicznie") // ale w jednym wątku main ("synchronicznie")
Watek1 watek1b = new Watek1(); Watek1 watek1b = new Watek1();
watek1b.start(); watek1b.start();
// 2) Implementacja interfejsu Runnable i utworzenie obiektu Thread na jej podstawie // 2) Implementacja interfejsu Runnable i utworzenie obiektu Thread na jej podstawie
class Watek2 implements Runnable { class Watek2 implements Runnable {
public void run() { public void run() {
System.out.println("Watek2 początek, id = " + Thread.currentThread().getId()); System.out.println("Watek2 początek, id = " + Thread.currentThread().getId());
for(int i = 1; i <= 10; i++) { for(int i = 1; i <= 10; i++) {
System.out.println("Watek2 działa, id = " + Thread.currentThread().getId() + ", i = " + i); System.out.println("Watek2 działa, id = " + Thread.currentThread().getId() + ", i = " + i);
} }
System.out.println("Watek2 koniec, id = " + Thread.currentThread().getId()); System.out.println("Watek2 koniec, id = " + Thread.currentThread().getId());
} }
} }
Watek2 watek2_instancja_runnable = new Watek2(); Watek2 watek2_instancja_runnable = new Watek2();
// to nie jest jeszcze wątek - bo nie dziedziliśmy z Thread // to nie jest jeszcze wątek - bo nie dziedziliśmy z Thread
// watek2_instancja_runnable.start(); // watek2_instancja_runnable.start();
Thread watek2a = new Thread(watek2_instancja_runnable); Thread watek2a = new Thread(watek2_instancja_runnable);
// wiele wątków opartych o ten sam obiekt Runnable? - OK // wiele wątków opartych o ten sam obiekt Runnable? - OK
Thread watek2b = new Thread(watek2_instancja_runnable); Thread watek2b = new Thread(watek2_instancja_runnable);
watek2a.start(); watek2a.start();
watek2b.start(); watek2b.start();
Thread watek2c = new Thread(new Watek2()); Thread watek2c = new Thread(new Watek2());
watek2c.start(); watek2c.start();
// Zwięzłe zapisy: klasa anonimowa, wyrażenie lambda // Zwięzłe zapisy: klasa anonimowa, wyrażenie lambda
Thread watek3a = new Thread(new Runnable() { Thread watek3a = new Thread(new Runnable() {
public void run() { public void run() {
System.out.println("wątek 3 a"); System.out.println("wątek 3 a");
} }
}); });
watek3a.start(); watek3a.start();
Thread watek3b = new Thread(() -> { Thread watek3b = new Thread(() -> {
System.out.println("wątek 3 b"); System.out.println("wątek 3 b");
}); });
watek3b.start(); watek3b.start();
new Thread(() -> { new Thread(() -> {
System.out.println("wątek 3 c"); System.out.println("wątek 3 c");
}).start(); }).start();
System.out.println("Koniec main"); System.out.println("Koniec main");
} }
} }
...@@ -3,40 +3,40 @@ package watki.gotowe.tworzenie; ...@@ -3,40 +3,40 @@ package watki.gotowe.tworzenie;
public class TworzenieWatkow_Alt { public class TworzenieWatkow_Alt {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("Początek main, nr wątku " + Thread.currentThread().getId()); System.out.println("Początek main, nr wątku " + Thread.currentThread().getId());
Thread watek1 = new Thread(new WatekA()); Thread watek1 = new Thread(new WatekA());
WatekB przepisB = new WatekB(); WatekB przepisB = new WatekB();
Thread watek2 = new Thread(przepisB); Thread watek2 = new Thread(przepisB);
Thread watek3 = new Thread(przepisB); // wiele wątków może korzystać z tego samego Runnable Thread watek3 = new Thread(przepisB); // wiele wątków może korzystać z tego samego Runnable
watek1.start(); watek1.start();
watek2.start(); watek2.start();
watek3.start(); watek3.start();
System.out.println("Wątki odpalone"); System.out.println("Wątki odpalone");
} }
// Obiekt klasy implementującej Runnable jest przepisem mówiącym "co ma robić wątek". // Obiekt klasy implementującej Runnable jest przepisem mówiącym "co ma robić wątek".
private static class WatekA implements Runnable { private static class WatekA implements Runnable {
@Override @Override
public void run() { public void run() {
System.out.println("Wątek A start, nr wątku " + Thread.currentThread().getId()); System.out.println("Wątek A start, nr wątku " + Thread.currentThread().getId());
for(int i = 1; i < 1000; i++) { for(int i = 1; i < 1000; i++) {
System.out.println("A"); System.out.println("A");
} }
System.out.println("Wątek A koniec"); System.out.println("Wątek A koniec");
} }
} }
private static class WatekB implements Runnable { private static class WatekB implements Runnable {
@Override @Override
public void run() { public void run() {
System.out.println("Wątek B start, nr wątku " + Thread.currentThread().getId()); System.out.println("Wątek B start, nr wątku " + Thread.currentThread().getId());
for(int i = 1; i < 1000; i++) { for(int i = 1; i < 1000; i++) {
System.out.println(" B"); System.out.println(" B");
} }
System.out.println("Wątek B koniec"); System.out.println("Wątek B koniec");
} }
} }
} }
package watki.gotowe.tworzenie;
public class Watek12_Program {
public static void main(String[] args) {
Watek1_Extends watek1 = new Watek1_Extends();
Watek2_Runnable trescWatku2 = new Watek2_Runnable();
Thread watek2 = new Thread(trescWatku2);
// "klasa anonimowa", do Java 7 był to najbradziej zwięzły zapis
Thread watek3 = new Thread(new Runnable() {
public void run() {
System.out.println("Startuje wątek 3. id = " + Thread.currentThread().getId());
for(int i = 1; i <= 1000; i++) {
System.out.println("Wątek 3: " + i);
}
System.out.println("Koniec wątek 3.");
}
});
// "wyrażenie lambda"
Thread watek4 = new Thread(() -> {
System.out.println("Startuje wątek 4. id = " + Thread.currentThread().getId());
for(int i = 1; i <= 1000; i++) {
System.out.println("Wątek 4: " + i);
}
System.out.println("Koniec wątek 4.");
});
watek1.start();
watek2.start();
watek3.start();
watek4.start();
System.out.println("Koniec main");
}
}
package watki.gotowe.tworzenie; package watki.gotowe.tworzenie;
public class Watek1_Extends extends Thread { public class Watek1_Extends extends Thread {
// Możemy określić własną treść - "co ma robić wątek" - nadpisując metodę run() // Możemy określić własną treść - "co ma robić wątek" - nadpisując metodę run()
@Override @Override
public void run() { public void run() {
System.out.println("Startuje wątek 1. id = " + Thread.currentThread().getId()); System.out.println("Startuje wątek 1. id = " + Thread.currentThread().getId());
for(int i = 1; i <= 1000; i++) { for(int i = 1; i <= 1000; i++) {
System.out.println("Wątek 1: " + i); System.out.println("Wątek 1: " + i);
} }
System.out.println("Koniec wątek 1."); System.out.println("Koniec wątek 1.");
} }
} }
...@@ -2,15 +2,13 @@ package watki.gotowe.tworzenie; ...@@ -2,15 +2,13 @@ package watki.gotowe.tworzenie;
public class Watek2_Runnable implements Runnable { public class Watek2_Runnable implements Runnable {
@Override @Override
public void run() { public void run() {
System.out.println("Startuje wątek 2. id = " + Thread.currentThread().getId()); System.out.println("Startuje wątek 2. id = " + Thread.currentThread().getId());
for(int i = 1; i <= 1000; i++) {
for(int i = 1; i <= 1000; i++) { System.out.println("Wątek 2: " + i);
System.out.println("Wątek 2: " + i); }
} System.out.println("Koniec wątek 2.");
}
System.out.println("Koniec wątek 2.");
}
} }
package watki.gotowe.tworzenie; package watki.gotowe.tworzenie;
class WatekWypisujacy implements Runnable { class WatekWypisujacy implements Runnable {
private final String tekst; private final String tekst;
private final int iloscPowtorzen; private final int iloscPowtorzen;
private final int pauza; private final int pauza;
public WatekWypisujacy(String tekst, int iloscPowtorzen, int pauza) { public WatekWypisujacy(String tekst, int iloscPowtorzen, int pauza) {
this.tekst = tekst; this.tekst = tekst;
this.iloscPowtorzen = iloscPowtorzen; this.iloscPowtorzen = iloscPowtorzen;
this.pauza = pauza; this.pauza = pauza;
} }
public void run() { public void run() {
System.out.println(tekst + " : start wątku, nr " + Thread.currentThread().getId()); System.out.println(tekst + " : start wątku, nr " + Thread.currentThread().getId());
try { try {
for(int i = 1; i <= iloscPowtorzen; i++) { for(int i = 1; i <= iloscPowtorzen; i++) {
if(pauza > 0) { if(pauza > 0) {
Thread.sleep(pauza); Thread.sleep(pauza);
} }
System.out.println(tekst + " " + i); System.out.println(tekst + " " + i);
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
System.err.println(e); System.err.println(e);
} }
System.out.println(tekst + " : koniec wątku, nr " + Thread.currentThread().getId()); System.out.println(tekst + " : koniec wątku, nr " + Thread.currentThread().getId());
} }
} }
...@@ -2,24 +2,24 @@ package watki.gotowe.tworzenie; ...@@ -2,24 +2,24 @@ package watki.gotowe.tworzenie;
public class Watki1 { public class Watki1 {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("Początek main"); System.out.println("Początek main");
Thread th1 = new Thread(new WatekWypisujacy("A", 100, 1)); Thread th1 = new Thread(new WatekWypisujacy("A", 100, 1));
Thread th2 = new Thread(new WatekWypisujacy("B", 100, 1)); Thread th2 = new Thread(new WatekWypisujacy("B", 100, 1));
Thread th3 = new Thread(new WatekWypisujacy("C", 100, 1)); Thread th3 = new Thread(new WatekWypisujacy("C", 100, 1));
th1.start(); th1.start();
th2.start(); th2.start();
th3.start(); th3.start();
System.out.println("main: wątki uruchomione"); System.out.println("main: wątki uruchomione");
try { try {
Thread.sleep(50); Thread.sleep(50);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
System.out.println("main: poczekałem sobie"); System.out.println("main: poczekałem sobie");
System.out.println("koniec main"); System.out.println("koniec main");
// main dochodzi do końca, a wątki działają dalej // main dochodzi do końca, a wątki działają dalej
} }
} }
...@@ -2,39 +2,39 @@ package watki.gotowe.tworzenie; ...@@ -2,39 +2,39 @@ package watki.gotowe.tworzenie;
public class Watki2_Join { public class Watki2_Join {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("Początek main"); System.out.println("Początek main");
Thread th1 = new Thread(new WatekWypisujacy("A", 100, 1)); Thread th1 = new Thread(new WatekWypisujacy("A", 100, 1));
Thread th2 = new Thread(new WatekWypisujacy("B", 100, 1)); Thread th2 = new Thread(new WatekWypisujacy("B", 100, 1));
Thread th3 = new Thread(new WatekWypisujacy("C", 100, 1)); Thread th3 = new Thread(new WatekWypisujacy("C", 100, 1));
System.out.println("stan przed start: " + th1.getState()); System.out.println("stan przed start: " + th1.getState());
th1.start(); th1.start();
th2.start(); th2.start();
th3.start(); th3.start();
System.out.println("main: wątki uruchomione, mój nr " + Thread.currentThread().getId()); System.out.println("main: wątki uruchomione, mój nr " + Thread.currentThread().getId());
try { try {
Thread.sleep(50); Thread.sleep(50);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
System.out.println("main: Teraz będę czekał na wątki za pomocą join"); System.out.println("main: Teraz będę czekał na wątki za pomocą join");
System.out.println("stan przed join: " + th1.getState()); System.out.println("stan przed join: " + th1.getState());
// wątek main czeka na zakończenie wątków th1, th2, th3 // wątek main czeka na zakończenie wątków th1, th2, th3
// jeśli one się skończyły wcześniej, to od razu przechodzi dalej // jeśli one się skończyły wcześniej, to od razu przechodzi dalej
try { try {
th1.join(); th1.join();
th2.join(); th2.join();
th3.join(); th3.join();
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
System.out.println("main: doczekałem się na zakończenie wątków"); System.out.println("main: doczekałem się na zakończenie wątków");
System.out.println("stan po join: " + th1.getState()); System.out.println("stan po join: " + th1.getState());
System.out.println("koniec main"); System.out.println("koniec main");
} }
} }
...@@ -2,33 +2,33 @@ package watki.gotowe.tworzenie; ...@@ -2,33 +2,33 @@ package watki.gotowe.tworzenie;
public class Watki3_Demon { public class Watki3_Demon {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("Początek main"); System.out.println("Początek main");
Thread th1 = new Thread(new WatekWypisujacy("A", 100, 1)); Thread th1 = new Thread(new WatekWypisujacy("A", 100, 1));
Thread th2 = new Thread(new WatekWypisujacy("B", 100, 1)); Thread th2 = new Thread(new WatekWypisujacy("B", 100, 1));
Thread th3 = new Thread(new WatekWypisujacy("C", 100, 1)); Thread th3 = new Thread(new WatekWypisujacy("C", 100, 1));
th1.setDaemon(true); th1.setDaemon(true);
th2.setDaemon(true); th2.setDaemon(true);
th3.setDaemon(true); th3.setDaemon(true);
th1.start(); th1.start();
th2.start(); th2.start();
th3.start(); th3.start();
// setDaemon wywołane po start jest niepoprawne - kończy się wyjątkiem // setDaemon wywołane po start jest niepoprawne - kończy się wyjątkiem
// th1.setDaemon(false); // th1.setDaemon(false);
// th1.setDaemon(true); // th1.setDaemon(true);
System.out.println("main: wątki uruchomione"); System.out.println("main: wątki uruchomione");
try { try {
Thread.sleep(60); Thread.sleep(60);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
System.out.println("main: poczekałem sobie"); System.out.println("main: poczekałem sobie");
System.out.println("koniec main"); System.out.println("koniec main");
// Jeśli w działaniu pozostały wyłącznie wątki będące demonami, to proces jest kończony (i te wątki są "zabijane" w dowolnym momencie). // Jeśli w działaniu pozostały wyłącznie wątki będące demonami, to proces jest kończony (i te wątki są "zabijane" w dowolnym momencie).
} }
} }
package watki.gotowe.tworzenie; package watki.gotowe.tworzenie;
class WatekAA extends Thread { class WatekAA extends Thread {
@Override @Override
public void run() { public void run() {
System.out.println("AA"); System.out.println("AA");
try { try {
Thread.sleep(500); Thread.sleep(500);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
System.out.println("AA"); System.out.println("AA");
throw new RuntimeException("masakra"); throw new RuntimeException("masakra");
//throw new Error("masakra"); // tak samo //throw new Error("masakra"); // tak samo
} }
} }
class WatekBB extends Thread { class WatekBB extends Thread {
@Override @Override
public void run() { public void run() {
for(int i =1; i <= 15; i++) { for(int i =1; i <= 15; i++) {
System.out.println("BB"); System.out.println("BB");
try { try {
Thread.sleep(333); Thread.sleep(333);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
} }
public class WyjatekWWatku { public class WyjatekWWatku {
public static void main(String[] args) { public static void main(String[] args) {
WatekAA watekB = new WatekAA(); WatekAA watekB = new WatekAA();
WatekBB watekC = new WatekBB(); WatekBB watekC = new WatekBB();
watekB.start(); watekB.start();
watekC.start(); watekC.start();
System.out.println("main: uruchomilem watki"); System.out.println("main: uruchomilem watki");
for(int i =1; i <= 10; i++) { for(int i =1; i <= 10; i++) {
System.out.println("MM"); System.out.println("MM");
try { try {
Thread.sleep(250); Thread.sleep(250);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
} }
...@@ -3,14 +3,14 @@ package watki.gotowe.util; ...@@ -3,14 +3,14 @@ package watki.gotowe.util;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
public class AtomowyLicznik { public class AtomowyLicznik {
private static AtomicInteger licznik; private static AtomicInteger licznik;
private static final int N = 10_000_000; private static final int N = 10_000_000;
private static class Watek implements Runnable { private static class Watek implements Runnable {
public void run() { public void run() {
for(int i=0; i<N; i++) { for(int i=0; i<N; i++) {
licznik.addAndGet(3); // += licznik.addAndGet(3); // +=
licznik.addAndGet(-3); // -= licznik.addAndGet(-3); // -=
// Number n = licznik; // OK // Number n = licznik; // OK
// licznik.incrementAndGet();// ++x // licznik.incrementAndGet();// ++x
...@@ -21,43 +21,43 @@ public class AtomowyLicznik { ...@@ -21,43 +21,43 @@ public class AtomowyLicznik {
// licznik.get(); // licznik.get();
// licznik.set(5); // licznik.set(5);
// licznik.compareAndSet(50, 1000); // tylko jeśli aktualna wartość to 50, to ustaw ową wartość 1000 // licznik.compareAndSet(50, 1000); // tylko jeśli aktualna wartość to 50, to ustaw ową wartość 1000
// Aby użycie takiego obiektu było poprawne, należy wykonywać operacje "jednym wywołaniem" // Aby użycie takiego obiektu było poprawne, należy wykonywać operacje "jednym wywołaniem"
// np. poprawne jest // np. poprawne jest
// licznik.addAndGet(5); // licznik.addAndGet(5);
// a niepoprawne byłoby // a niepoprawne byłoby
// int x = licznik.get(); // int x = licznik.get();
// licznik.set(x + 5); // licznik.set(x + 5);
// poprawne: // poprawne:
// licznik.compareAndSet(100, 0); // licznik.compareAndSet(100, 0);
// niepoprawne // niepoprawne
// if(licznik.get() == 100) { // if(licznik.get() == 100) {
// licznik.set(0); // licznik.set(0);
// } // }
} }
} }
} }
public static void main(String[] args) { public static void main(String[] args) {
licznik = new AtomicInteger(10000); licznik = new AtomicInteger(10000);
System.out.println(licznik); System.out.println(licznik);
Thread th1 = new Thread(new Watek()); Thread th1 = new Thread(new Watek());
Thread th2 = new Thread(new Watek()); Thread th2 = new Thread(new Watek());
th1.start(); th1.start();
th2.start(); th2.start();
System.out.println("Uruchomiłem"); System.out.println("Uruchomiłem");
try { try {
th1.join(); th1.join();
th2.join(); th2.join();
} catch(InterruptedException e) { } catch(InterruptedException e) {
} }
System.out.println("Wątki zakończone"); System.out.println("Wątki zakończone");
System.out.println(licznik.get()); System.out.println(licznik.get());
} }
} }
...@@ -4,46 +4,46 @@ import java.util.concurrent.BrokenBarrierException; ...@@ -4,46 +4,46 @@ import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier; import java.util.concurrent.CyclicBarrier;
public class Bariery { public class Bariery {
static final int N = 6; static final int N = 6;
static volatile boolean koniec = false; static volatile boolean koniec = false;
public static void main(String[] args) { public static void main(String[] args) {
final CyclicBarrier bariera = new CyclicBarrier(4); final CyclicBarrier bariera = new CyclicBarrier(4);
class MojRunnable implements Runnable { class MojRunnable implements Runnable {
public void run() { public void run() {
while(!koniec) { while(!koniec) {
try { try {
System.out.println("Czeka "+Thread.currentThread().getId()); System.out.println("Czeka "+Thread.currentThread().getId());
bariera.await(); bariera.await();
System.out.println("Doczekal "+Thread.currentThread().getId()); System.out.println("Doczekal "+Thread.currentThread().getId());
Thread.sleep(400+Thread.currentThread().getId()*100); Thread.sleep(400+Thread.currentThread().getId()*100);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} catch (BrokenBarrierException e) { } catch (BrokenBarrierException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
} }
MojRunnable runable = new MojRunnable(); MojRunnable runable = new MojRunnable();
for(int i = 0; i < N; i++) { for(int i = 0; i < N; i++) {
new Thread(runable).start(); new Thread(runable).start();
try { try {
Thread.sleep(200); Thread.sleep(200);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
try { try {
Thread.sleep(8000); Thread.sleep(8000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
System.out.println("main: reset"); System.out.println("main: reset");
koniec = true; koniec = true;
bariera.reset(); bariera.reset();
System.out.println("Koniec"); System.out.println("Koniec");
} }
} }
...@@ -3,50 +3,50 @@ package watki.gotowe.util; ...@@ -3,50 +3,50 @@ package watki.gotowe.util;
import java.util.concurrent.Phaser; import java.util.concurrent.Phaser;
public class Fazery1 { public class Fazery1 {
static boolean koniec = false; static boolean koniec = false;
static final int N = 3; static final int N = 3;
public static void main(String[] args) { public static void main(String[] args) {
final Phaser ph = new Phaser(3); final Phaser ph = new Phaser(3);
class Watek implements Runnable { class Watek implements Runnable {
public void run() { public void run() {
while(!koniec) { while(!koniec) {
try { try {
System.out.println("Czeka "+Thread.currentThread().getId()); System.out.println("Czeka "+Thread.currentThread().getId());
ph.arriveAndAwaitAdvance(); ph.arriveAndAwaitAdvance();
System.out.println("Doczekal "+Thread.currentThread().getId() + " faza "+ph.getPhase()); System.out.println("Doczekal "+Thread.currentThread().getId() + " faza "+ph.getPhase());
Thread.sleep(400+Thread.currentThread().getId()*100); Thread.sleep(400+Thread.currentThread().getId()*100);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
} }
Watek runable = new Watek(); Watek runable = new Watek();
for(int i = 0; i < N; i++) { for(int i = 0; i < N; i++) {
new Thread(runable).start(); new Thread(runable).start();
try { try {
Thread.sleep(700); Thread.sleep(700);
} catch (InterruptedException e) { } catch (InterruptedException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
} }
try { try {
Thread.sleep(8000); Thread.sleep(8000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
koniec = true; koniec = true;
ph.forceTermination(); ph.forceTermination();
System.out.println("Koniec"); System.out.println("Koniec");
} }
} }
...@@ -3,54 +3,54 @@ package watki.gotowe.util; ...@@ -3,54 +3,54 @@ package watki.gotowe.util;
import java.util.concurrent.Phaser; import java.util.concurrent.Phaser;
public class Fazery2 { public class Fazery2 {
static boolean koniec = false; static boolean koniec = false;
static final int N = 3; static final int N = 3;
public static void main(String[] args) { public static void main(String[] args) {
final Phaser ph = new Phaser(3); final Phaser ph = new Phaser(3);
class Watek implements Runnable { class Watek implements Runnable {
private int nastFaza; private int nastFaza;
public Watek(boolean parzyste) { public Watek(boolean parzyste) {
nastFaza = parzyste ? 2 : 1; nastFaza = parzyste ? 2 : 1;
} }
public void run() { public void run() {
while(!koniec) { while(!koniec) {
try { try {
Thread.sleep(500+Thread.currentThread().getId()*100); Thread.sleep(500+Thread.currentThread().getId()*100);
int faza = ph.arrive(); int faza = ph.arrive();
System.out.println("Przybylem "+Thread.currentThread().getId() + " czekam na "+nastFaza); System.out.println("Przybylem "+Thread.currentThread().getId() + " czekam na "+nastFaza);
ph.awaitAdvance(faza); ph.awaitAdvance(faza);
System.out.println("Doczekalem "+Thread.currentThread().getId() + " faza "+ph.getPhase()); System.out.println("Doczekalem "+Thread.currentThread().getId() + " faza "+ph.getPhase());
nastFaza += 2; nastFaza += 2;
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
} }
for(int i = 0; i < N; i++) { for(int i = 0; i < N; i++) {
new Thread(new Watek(true)).start(); new Thread(new Watek(true)).start();
new Thread(new Watek(false)).start(); new Thread(new Watek(false)).start();
try { try {
Thread.sleep(200); Thread.sleep(200);
} catch (InterruptedException e) { } catch (InterruptedException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
} }
try { try {
Thread.sleep(8000); Thread.sleep(8000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
koniec = true; koniec = true;
ph.forceTermination(); ph.forceTermination();
System.out.println("Koniec"); System.out.println("Koniec");
} }
} }
...@@ -4,39 +4,39 @@ import java.util.concurrent.CountDownLatch; ...@@ -4,39 +4,39 @@ import java.util.concurrent.CountDownLatch;
public class Odliczanie { public class Odliczanie {
public static void main(String[] args) { public static void main(String[] args) {
final CountDownLatch guzik = new CountDownLatch(10); final CountDownLatch guzik = new CountDownLatch(10);
Thread rakieta = new Thread(new Runnable() { Thread rakieta = new Thread(new Runnable() {
public void run() { public void run() {
try { try {
System.out.println("Rakieta w przygotowaniu"); System.out.println("Rakieta w przygotowaniu");
Thread.sleep(750); Thread.sleep(750);
System.out.println("Rakieta przygotowana..."); System.out.println("Rakieta przygotowana...");
guzik.await(); guzik.await();
System.out.println("Start!!!"); System.out.println("Start!!!");
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
}); });
Thread kontrola = new Thread(new Runnable() { Thread kontrola = new Thread(new Runnable() {
public void run() { public void run() {
System.out.println("Kontrola zaczyna odliczanie"); System.out.println("Kontrola zaczyna odliczanie");
while(guzik.getCount() > 0) { while(guzik.getCount() > 0) {
try { try {
Thread.sleep(1000); Thread.sleep(1000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
guzik.countDown(); guzik.countDown();
System.out.println("> " + guzik.getCount()); System.out.println("> " + guzik.getCount());
} } }); } } });
System.out.println("Ruszamy"); System.out.println("Ruszamy");
rakieta.start(); rakieta.start();
kontrola.start(); kontrola.start();
System.out.println("Koniec main"); System.out.println("Koniec main");
} }
} }
...@@ -4,41 +4,41 @@ import java.util.concurrent.Exchanger; ...@@ -4,41 +4,41 @@ import java.util.concurrent.Exchanger;
public class Wymiana { public class Wymiana {
public static void main(String[] args) { public static void main(String[] args) {
final Exchanger<String> schowek = new Exchanger<>(); final Exchanger<String> schowek = new Exchanger<>();
Thread th1 = new Thread(new Runnable() { Thread th1 = new Thread(new Runnable() {
public void run() { public void run() {
String imie = "Ala"; String imie = "Ala";
System.out.printf("Jestem %s w wątku %d%n", imie, Thread.currentThread().getId()); System.out.printf("Jestem %s w wątku %d%n", imie, Thread.currentThread().getId());
try { try {
Thread.sleep(100); Thread.sleep(100);
String twojeImie = schowek.exchange(imie); String twojeImie = schowek.exchange(imie);
System.out.printf("Wątek %d, twoje imię to %s %n", Thread.currentThread().getId(), twojeImie); System.out.printf("Wątek %d, twoje imię to %s %n", Thread.currentThread().getId(), twojeImie);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
}); });
Thread th2 = new Thread(new Runnable() { Thread th2 = new Thread(new Runnable() {
public void run() { public void run() {
String imie = "Tomek"; String imie = "Tomek";
System.out.printf("Jestem %s w wątku %d%n", imie, Thread.currentThread().getId()); System.out.printf("Jestem %s w wątku %d%n", imie, Thread.currentThread().getId());
try { try {
Thread.sleep(3000); Thread.sleep(3000);
String twojeImie = schowek.exchange(imie); String twojeImie = schowek.exchange(imie);
System.out.printf("Wątek %d, twoje imię to %s %n", Thread.currentThread().getId(), twojeImie); System.out.printf("Wątek %d, twoje imię to %s %n", Thread.currentThread().getId(), twojeImie);
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
}); });
th1.start(); th1.start();
th2.start(); th2.start();
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment