Commit 067dfbfa by Patryk Czarnik

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

parent 51cdd831
package watki.gotowe.ilustracje_nie_do_uruchamiania;
public class Afrykarium1 {
// wolne miejsca w środku
private int wolne = 2000;
// wolne miejsca w środku
private int wolne = 2000;
public synchronized void wpuśćWycieczkę(int ilu) {
try {
while(wolne < ilu) {
this.wait();
}
wolne -= ilu;
// otwórz bramki
} catch(InterruptedException e) {
}
}
public synchronized void wpuśćWycieczkę(int ilu) {
try {
while(wolne < ilu) {
this.wait();
}
wolne -= ilu;
// otwórz bramki
} catch(InterruptedException e) {
}
}
public synchronized void zwiedzającyWychodzi() {
wolne++;
notify();
}
public synchronized void zwiedzającyWychodzi() {
wolne++;
notify();
}
}
......@@ -5,34 +5,34 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Afrykarium2 {
// wolne miejsca w środku
private int miejsca = 2000;
// synchronizacja
private Lock ochrona = new ReentrantLock();
private Condition czekanieNaMiejsca = ochrona.newCondition();
// wolne miejsca w środku
private int miejsca = 2000;
// synchronizacja
private Lock ochrona = new ReentrantLock();
private Condition czekanieNaMiejsca = ochrona.newCondition();
public void wpuśćWycieczkę(int ilu) {
try {
ochrona.lock();
while(miejsca < ilu) {
czekanieNaMiejsca.await();
}
miejsca -= ilu;
// otwórz bramki
} catch(InterruptedException e) {
} finally {
ochrona.unlock();
}
}
public void wpuśćWycieczkę(int ilu) {
try {
ochrona.lock();
while(miejsca < ilu) {
czekanieNaMiejsca.await();
}
miejsca -= ilu;
// otwórz bramki
} catch(InterruptedException e) {
} finally {
ochrona.unlock();
}
}
public void zwiedzającyWychodzi() {
try {
ochrona.lock();
miejsca++;
czekanieNaMiejsca.signal();
} finally {
ochrona.unlock();
}
}
public void zwiedzającyWychodzi() {
try {
ochrona.lock();
miejsca++;
czekanieNaMiejsca.signal();
} finally {
ochrona.unlock();
}
}
}
......@@ -3,20 +3,20 @@ package watki.gotowe.ilustracje_nie_do_uruchamiania;
import java.util.concurrent.Semaphore;
public class Afrykarium3 {
// wolne miejsca w środku
private Semaphore miejsca = new Semaphore(2000, true);
// wolne miejsca w środku
private Semaphore miejsca = new Semaphore(2000, true);
public void wpuśćWycieczkę(int ilu) {
try {
// zmniejsza wartość semafora o ilu,
// ale jeśli wartość semafora < ilu, to czeka, aż semafor uzyska odp. wartość.
miejsca.acquire(ilu); // -= akademicko : P
} catch(InterruptedException e) {
}
// otwórz bramki
}
public void wpuśćWycieczkę(int ilu) {
try {
// zmniejsza wartość semafora o ilu,
// ale jeśli wartość semafora < ilu, to czeka, aż semafor uzyska odp. wartość.
miejsca.acquire(ilu); // -= akademicko : P
} catch(InterruptedException e) {
}
// otwórz bramki
}
public void zwiedzającyWychodzi() {
miejsca.release(); // ++ akademicko: V
}
public void zwiedzającyWychodzi() {
miejsca.release(); // ++ akademicko: V
}
}
package watki.gotowe.ilustracje_nie_do_uruchamiania;
public class InstancyjnaIStatyczna {
synchronized void instancyjna1() {
}
synchronized void instancyjna1() {
}
synchronized void instancyjna2() {
// instancyjne synchronizują się na poszczególnych obiektach
}
synchronized void instancyjna2() {
// instancyjne synchronizują się na poszczególnych obiektach
}
static synchronized void statyczna1() {
}
static synchronized void statyczna2() {
// statyczne wzajemnie się synchronizują
// na obiekcie InstancyjnaIStatyczna.class
// statyczne i instancyjne wzajemnie się nie synchronizują
}
void metoda() {
// gdybym chciał się zsynchronizować z metodami statycznymi, to mogę tak:
synchronized(InstancyjnaIStatyczna.class) {
}
// tak jak
synchronized(this) {
// jest synchronizacją na bieżącym obiekcie
// z tym że tutaj i tak nic nie robi, bo jesteśmy w metodzie synchronized
}
}
static synchronized void statyczna1() {
}
static synchronized void statyczna2() {
// statyczne wzajemnie się synchronizują
// na obiekcie InstancyjnaIStatyczna.class
// statyczne i instancyjne wzajemnie się nie synchronizują
}
void metoda() {
// gdybym chciał się zsynchronizować z metodami statycznymi, to mogę tak:
synchronized(InstancyjnaIStatyczna.class) {
}
// tak jak
synchronized(this) {
// jest synchronizacją na bieżącym obiekcie
// z tym że tutaj i tak nic nie robi, bo jesteśmy w metodzie synchronized
}
}
}
package watki.gotowe.kolekcje;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
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;
import java.util.concurrent.*;
/* 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
* - 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.
*/
public class ConcMap {
// liczba wątków
private static final int N = 16;
// wielkość słownika
private static final int K = 100;
// ilość powtórzeń jednej operacji
private static final int P = 50;
// liczba wątków
private static final int N = 16;
// wielkość słownika
private static final int K = 100;
// ilość powtórzeń jednej operacji
private static final int P = 50;
// ilość powtórzeń całości
private static final int R = 10_000;
// ilość powtórzeń całości
private static final int R = 10_000;
// odkomentuj jedną z wersji i sprawdź
//private final Map<String, Integer> map = Collections.synchronizedMap(new HashMap<>());
private final Map<String, Integer> map = new ConcurrentHashMap<>();
//private final ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>();
// odkomentuj jedną z wersji i sprawdź
//private final Map<String, Integer> map = Collections.synchronizedMap(new HashMap<>());
private final Map<String, Integer> map = new ConcurrentHashMap<>();
//private final ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>();
private void dzialaj() {
final ThreadLocalRandom random = ThreadLocalRandom.current();
for(int r=0; r < R; r++) {
final int k = random.nextInt(K);
final int d = random.nextInt(1000) - 500;
final String key = String.valueOf(k);
for(int p = 0; p < P; p++) {
Integer v = map.merge(key, d, (x, y) -> x+y);
//System.out.println(r + " " + p);
}
}
}
public static void main(String[] args) {
ConcMap instance = new ConcMap();
ExecutorService pool = Executors.newFixedThreadPool(N);
System.out.println("Start");
long start = System.currentTimeMillis();
for(int i = 0; i < N; i++) {
pool.submit(instance::dzialaj);
}
try {
pool.shutdown();
pool.awaitTermination(1, TimeUnit.HOURS);
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("Czas: " + (end - start));
}
private void dzialaj() {
final ThreadLocalRandom random = ThreadLocalRandom.current();
for(int r=0; r < R; r++) {
final int k = random.nextInt(K);
final int d = random.nextInt(1000) - 500;
final String key = String.valueOf(k);
for(int p = 0; p < P; p++) {
Integer v = map.merge(key, d, (x, y) -> x+y);
//System.out.println(r + " " + p);
}
}
}
public static void main(String[] args) {
ConcMap instance = new ConcMap();
ExecutorService pool = Executors.newFixedThreadPool(N);
System.out.println("Start");
long start = System.currentTimeMillis();
for(int i = 0; i < N; i++) {
pool.submit(instance::dzialaj);
}
try {
pool.shutdown();
pool.awaitTermination(1, TimeUnit.HOURS);
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("Czas: " + (end - start));
}
}
......@@ -3,8 +3,6 @@ package watki.gotowe.kolekcje;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadLocalRandom;
......@@ -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.
*/
public class ConcMap_Zwykle {
// liczba wątków
private static final int N = 16;
// wielkość słownika
private static final int K = 100;
// ilość powtórzeń jednej operacji
private static final int P = 50;
// liczba wątków
private static final int N = 16;
// wielkość słownika
private static final int K = 100;
// ilość powtórzeń jednej operacji
private static final int P = 50;
// ilość powtórzeń całości
private static final int R = 10_000;
// ilość powtórzeń całości
private static final int R = 10_000;
// odkomentuj jedną z wersji i sprawdź
private final Map<String, Integer> map = Collections.synchronizedMap(new HashMap<>());
// private final Map<String, Integer> map = new ConcurrentHashMap<>();
// private final ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>();
// odkomentuj jedną z wersji i sprawdź
private final Map<String, Integer> map = Collections.synchronizedMap(new HashMap<>());
// private final Map<String, Integer> map = new ConcurrentHashMap<>();
// private final ConcurrentMap<String, Integer> map = new ConcurrentHashMap<>();
private void dzialaj() {
final ThreadLocalRandom random = ThreadLocalRandom.current();
for(int r=0; r < R; r++) {
final int k = random.nextInt(K);
final int d = random.nextInt(1000) - 500;
final String key = String.valueOf(k);
for(int p = 0; p < P; p++) {
Integer v = map.merge(key, d, (x, y) -> x+y);
//System.out.println(r + " " + p);
}
}
}
public static void main(String[] args) {
ConcMap_Zwykle instance = new ConcMap_Zwykle();
ExecutorService pool = Executors.newFixedThreadPool(N);
System.out.println("Start");
long start = System.currentTimeMillis();
for(int i = 0; i < N; i++) {
pool.submit(instance::dzialaj);
}
try {
pool.shutdown();
pool.awaitTermination(1, TimeUnit.HOURS);
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("Czas: " + (end - start));
}
private void dzialaj() {
final ThreadLocalRandom random = ThreadLocalRandom.current();
for(int r=0; r < R; r++) {
final int k = random.nextInt(K);
final int d = random.nextInt(1000) - 500;
final String key = String.valueOf(k);
for(int p = 0; p < P; p++) {
Integer v = map.merge(key, d, (x, y) -> x+y);
//System.out.println(r + " " + p);
}
}
}
public static void main(String[] args) {
ConcMap_Zwykle instance = new ConcMap_Zwykle();
ExecutorService pool = Executors.newFixedThreadPool(N);
System.out.println("Start");
long start = System.currentTimeMillis();
for(int i = 0; i < N; i++) {
pool.submit(instance::dzialaj);
}
try {
pool.shutdown();
pool.awaitTermination(1, TimeUnit.HOURS);
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("Czas: " + (end - start));
}
}
......@@ -6,44 +6,44 @@ import java.util.concurrent.CopyOnWriteArrayList;
public class CopyArray {
public static void main(String[] args) {
// Kolekcje "CopyOnWrite" kopiują całą swoją _wewnętrzną_ tablicę gdy tylko ktokolwiek cokolwiek modyfikuje.
// Jeśli wcześniej został utworzony iterator ("ktoś czyta kolekcję"),
// to NIE jest on unieważniany, tylko daje obraz kolekcji sprzed zmiany ("snapshot").
// Iteratory NIE wyrzucają ConcurrrentModificationException.
// Iteratory dają dostęp tylko do odczytu.
List<String> lista = new CopyOnWriteArrayList<>();
lista.add("Ala");
lista.add("Basia");
lista.add("Celina");
Iterator<String> it1 = lista.iterator();
lista.add("Dorota");
lista.add("Eliza");
Iterator<String> it2 = lista.iterator();
lista.add("Felicja");
lista.add("Grażyna");
System.out.print("it1: ");
while(it1.hasNext()) {
System.out.print(it1.next() + " ");
}
System.out.println();
System.out.print("it2: ");
while(it2.hasNext()) {
System.out.print(it2.next() + " ");
// it2.remove(); // EXN
}
System.out.println();
System.out.print("lista: ");
for(String x : lista) {
System.out.print(x + " ");
}
System.out.println();
}
public static void main(String[] args) {
// Kolekcje "CopyOnWrite" kopiują całą swoją _wewnętrzną_ tablicę gdy tylko ktokolwiek cokolwiek modyfikuje.
// Jeśli wcześniej został utworzony iterator ("ktoś czyta kolekcję"),
// to NIE jest on unieważniany, tylko daje obraz kolekcji sprzed zmiany ("snapshot").
// Iteratory NIE wyrzucają ConcurrrentModificationException.
// Iteratory dają dostęp tylko do odczytu.
List<String> lista = new CopyOnWriteArrayList<>();
lista.add("Ala");
lista.add("Basia");
lista.add("Celina");
Iterator<String> it1 = lista.iterator();
lista.add("Dorota");
lista.add("Eliza");
Iterator<String> it2 = lista.iterator();
lista.add("Felicja");
lista.add("Grażyna");
System.out.print("it1: ");
while(it1.hasNext()) {
System.out.print(it1.next() + " ");
}
System.out.println();
System.out.print("it2: ");
while(it2.hasNext()) {
System.out.print(it2.next() + " ");
// it2.remove(); // EXN
}
System.out.println();
System.out.print("lista: ");
for(String x : lista) {
System.out.print(x + " ");
}
System.out.println();
}
}
package watki.gotowe.kolekcje;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
import java.util.*;
public class OpakowywanieSync {
public static void main(String[] args) {
// Vector, Hashtable, StringBuffer - stare klasy Javy, które są "thread-safe"
StringBuffer s;
Vector v;
Hashtable h;
List<String> zwykla = new ArrayList<>();
zwykla.add("Ala");
zwykla.add("Ola");
zwykla.add("Ela");
List<String> synchronizowana = Collections.synchronizedList(zwykla);
System.out.println(synchronizowana.getClass());
System.out.println("Zawartość zwykłej: " + zwykla);
System.out.println("Zawartość synchr: " + synchronizowana);
System.out.println();
zwykla.add("Ula");
synchronizowana.add("Ewa");
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:
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 wiele wątków będzie wykonywać taki kod, to dwa wątki mogą usuwać element z jednoelementowej listy -> błąd
if(synchronizowana.size() > 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) {
// skomplikowane operacje na liście...
if(synchronizowana.size() > 0) {
// teraz te dwie operacje będą wykonane atomowo
synchronizowana.remove(0);
}
for (String element : synchronizowana) {
// ...
// mamy pewność, że w czasie przeglądania inne wątki nie będą ruszać tej listy
}
}
}
public static void main(String[] args) {
// Vector, Hashtable, StringBuffer - stare klasy Javy, które są "thread-safe"
StringBuffer s;
Vector v;
Hashtable h;
// Współczesne ich wersje bez synchronizacji: StringBuilder, ArrayList, HashMap
List<String> zwykla = new ArrayList<>();
zwykla.add("Ala");
zwykla.add("Ola");
zwykla.add("Ela");
List<String> synchronizowana = Collections.synchronizedList(zwykla);
System.out.println(synchronizowana.getClass());
System.out.println("Zawartość zwykłej: " + zwykla);
System.out.println("Zawartość synchr: " + synchronizowana);
System.out.println();
zwykla.add("Ula");
synchronizowana.add("Ewa");
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:
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łędu:
// Jeśli wiele wątków będzie wykonywać taki kod, to dwa wątki mogą usuwać element z jednoelementowej listy -> błąd
if(synchronizowana.size() > 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) {
// skomplikowane operacje na liście...
if(synchronizowana.size() > 0) {
// teraz te dwie operacje będą wykonane atomowo
synchronizowana.remove(0);
}
for (String element : synchronizowana) {
// ...
// mamy pewność, że w czasie przeglądania inne wątki nie będą ruszać tej listy
}
}
}
}
......@@ -2,70 +2,68 @@ package watki.gotowe.kolekcje;
import java.util.concurrent.ArrayBlockingQueue;
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.
public class ProdKons1 {
private static final int ILE_RAZY = 30;
private static final int N = 5;
private BlockingQueue<Integer> kolejka = new ArrayBlockingQueue<>(N);
public static void main(String[] args) {
ProdKons1 program = new ProdKons1();
program.dzialaj();
}
private void dzialaj() {
Thread producent = new Thread(new Producent());
Thread konsument = new Thread(new Konsument());
System.out.println("Startujemy");
producent.start();
konsument.start();
private static final int ILE_RAZY = 30;
private static final int N = 5;
private BlockingQueue<Integer> kolejka = new ArrayBlockingQueue<>(N);
public static void main(String[] args) {
ProdKons1 program = new ProdKons1();
program.dzialaj();
}
private void dzialaj() {
Thread producent = new Thread(new Producent());
Thread konsument = new Thread(new Konsument());
System.out.println("Startujemy");
producent.start();
konsument.start();
try {
producent.join();
} catch (InterruptedException e) {
}
try {
konsument.join();
} catch (InterruptedException e) {
}
System.out.println("Koniec. size="+kolejka.size());
}
try {
producent.join();
} catch (InterruptedException e) {
}
try {
konsument.join();
} catch (InterruptedException e) {
}
System.out.println("Koniec. size="+kolejka.size());
}
private class Producent implements Runnable {
public void run() {
for(int i=1; i<=ILE_RAZY; i++) {
int x = (int) (Math.random() * 1000);
System.out.println("P: wstawiam " + x);
try {
kolejka.put(x);
System.out.println("P: Wstawiłem, size=" + kolejka.size() );
Thread.sleep(300 + x);
} catch (InterruptedException e) {
}
}
}
}
private class Producent implements Runnable {
public void run() {
for(int i=1; i<=ILE_RAZY; i++) {
int x = (int) (Math.random() * 1000);
System.out.println("P: wstawiam " + x);
try {
kolejka.put(x);
System.out.println("P: Wstawiłem, size=" + kolejka.size() );
Thread.sleep(300 + x);
} catch (InterruptedException e) {
}
}
}
}
private class Konsument implements Runnable {
public void run() {
for(int i=1; i<=ILE_RAZY; i++) {
try {
Thread.sleep(100);
System.out.println(" K: Biorę...");
int x = kolejka.take();
//int x = kolejka.poll(100, TimeUnit.DAYS);
System.out.println(" K: ... Pobrałem " + x);
Thread.sleep(2*x);
} catch (InterruptedException e) {
}
}
}
}
private class Konsument implements Runnable {
public void run() {
for(int i=1; i<=ILE_RAZY; i++) {
try {
Thread.sleep(100);
System.out.println(" K: Biorę...");
int x = kolejka.take();
//int x = kolejka.poll(100, TimeUnit.DAYS);
System.out.println(" K: ... Pobrałem " + x);
Thread.sleep(2*x);
} catch (InterruptedException e) {
}
}
}
}
}
......@@ -4,60 +4,60 @@ import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class ProdKons2 {
private static final int ILE_RAZY = 30;
private BlockingQueue<Integer> kolejka = new LinkedBlockingQueue<>();
private static final int ILE_RAZY = 30;
private BlockingQueue<Integer> kolejka = new LinkedBlockingQueue<>();
public static void main(String[] args) {
ProdKons2 program = new ProdKons2();
program.dzialaj();
}
private void dzialaj() {
Thread producent = new Thread(new Producent());
Thread konsument = new Thread(new Konsument());
System.out.println("Startujemy");
producent.start();
konsument.start();
public static void main(String[] args) {
ProdKons2 program = new ProdKons2();
program.dzialaj();
}
private void dzialaj() {
Thread producent = new Thread(new Producent());
Thread konsument = new Thread(new Konsument());
System.out.println("Startujemy");
producent.start();
konsument.start();
try {
producent.join();
} catch (InterruptedException e) {
}
try {
konsument.join();
} catch (InterruptedException e) {
}
System.out.println("Koniec. size="+kolejka.size());
}
try {
producent.join();
} catch (InterruptedException e) {
}
try {
konsument.join();
} catch (InterruptedException e) {
}
System.out.println("Koniec. size="+kolejka.size());
}
private class Producent implements Runnable {
public void run() {
for(int i=1; i<=ILE_RAZY; i++) {
int x = (int) (Math.random() * 1000);
System.out.println("P: wstawiam " + x);
try {
kolejka.put(x);
System.out.println("P: Wstawiłem, size=" + kolejka.size() );
Thread.sleep(300 + x);
} catch (InterruptedException e) {
}
}
}
}
private class Producent implements Runnable {
public void run() {
for(int i=1; i<=ILE_RAZY; i++) {
int x = (int) (Math.random() * 1000);
System.out.println("P: wstawiam " + x);
try {
kolejka.put(x);
System.out.println("P: Wstawiłem, size=" + kolejka.size() );
Thread.sleep(300 + x);
} catch (InterruptedException e) {
}
}
}
}
private class Konsument implements Runnable {
public void run() {
for(int i=1; i<=ILE_RAZY; i++) {
try {
Thread.sleep(100);
System.out.println(" K: Biorę...");
int x = kolejka.take();
System.out.println(" K: ... Pobrałem " + x);
Thread.sleep(2*x);
} catch (InterruptedException e) {
}
}
}
}
private class Konsument implements Runnable {
public void run() {
for(int i=1; i<=ILE_RAZY; i++) {
try {
Thread.sleep(100);
System.out.println(" K: Biorę...");
int x = kolejka.take();
System.out.println(" K: ... Pobrałem " + x);
Thread.sleep(2*x);
} catch (InterruptedException e) {
}
}
}
}
}
package watki.gotowe.konta.v1_brak_synchronizacji;
public class BrakSrodkow extends Exception {
private static final long serialVersionUID = 5262944731342409658L;
private static final long serialVersionUID = 5262944731342409658L;
public BrakSrodkow() {
super();
}
public BrakSrodkow() {
super();
}
public BrakSrodkow(String message) {
super(message);
}
public BrakSrodkow(String message) {
super(message);
}
}
package watki.gotowe.konta.v1_brak_synchronizacji;
class Konto {
private final int numer;
private int saldo;
private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
public Osoba getWlasciciel() {
return wlasciciel;
}
public void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel;
}
public int getNumer() {
return numer;
}
public int getSaldo() {
return saldo;
}
public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel;
}
public void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
saldo += kwota;
}
public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
saldo -= kwota;
}
private final int numer;
private int saldo;
private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
public Osoba getWlasciciel() {
return wlasciciel;
}
public void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel;
}
public int getNumer() {
return numer;
}
public int getSaldo() {
return saldo;
}
public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel;
}
public void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
saldo += kwota;
}
public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
saldo -= kwota;
}
}
......@@ -4,63 +4,63 @@ import java.time.LocalDate;
import java.time.Period;
class Osoba {
private String imie, nazwisko;
private LocalDate dataUrodzenia;
public Osoba() {
}
Osoba(String imie, String nazwisko) {
this.imie = imie;
this.nazwisko = nazwisko;
}
private String imie, nazwisko;
private LocalDate dataUrodzenia;
public Osoba() {
}
Osoba(String imie, String nazwisko) {
this.imie = imie;
this.nazwisko = nazwisko;
}
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.setImie(imie);
this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia;
}
public Osoba(String imie, String nazwisko, String dataUrodzenia) {
// wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
}
public int obliczWiek() {
LocalDate dzisiaj = LocalDate.now();
Period wiek = Period.between(dataUrodzenia, dzisiaj);
return wiek.getYears();
}
@Override
public String toString() {
return imie + " " +nazwisko + " ur." + dataUrodzenia;
}
public String kimJestes() {
return "Jestem osobą";
}
public String getImie() {
return imie;
}
public String getNazwisko() {
return nazwisko;
}
public LocalDate getDataUrodzenia() {
return dataUrodzenia;
}
public void setImie(String imie) {
if(imie == null || imie.isEmpty()) {
throw new IllegalArgumentException("imię nie może być puste");
}
this.imie = imie;
}
public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.setImie(imie);
this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia;
}
public Osoba(String imie, String nazwisko, String dataUrodzenia) {
// wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
}
public int obliczWiek() {
LocalDate dzisiaj = LocalDate.now();
Period wiek = Period.between(dataUrodzenia, dzisiaj);
return wiek.getYears();
}
@Override
public String toString() {
return imie + " " +nazwisko + " ur." + dataUrodzenia;
}
public String kimJestes() {
return "Jestem osobą";
}
public String getImie() {
return imie;
}
public String getNazwisko() {
return nazwisko;
}
public LocalDate getDataUrodzenia() {
return dataUrodzenia;
}
public void setImie(String imie) {
if(imie == null || imie.isEmpty()) {
throw new IllegalArgumentException("imię nie może być puste");
}
this.imie = imie;
}
public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}
}
......@@ -4,45 +4,45 @@ import java.time.LocalDate;
class Przeploty {
public static void main(String[] args) {
final int N = 100_000;
final int KWOTA = 10;
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now());
Konto konto = new Konto(1, 1000_000, ala);
System.out.println(konto);
Thread wplacacz = new Thread(() -> {
for(int i = 0 ; i < N; i++) {
konto.wplata(KWOTA);
}
});
Thread wyplacacz = new Thread(() -> {
for(int i = 0; i < N; i++) {
try {
konto.wyplata(KWOTA);
} catch (BrakSrodkow e) {
System.err.println(e.getMessage());
}
}
});
System.out.println("Uruchamiam wątki");
wplacacz.start();
wyplacacz.start();
public static void main(String[] args) {
final int N = 100_000;
final int KWOTA = 10;
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now());
Konto konto = new Konto(1, 1000_000, ala);
System.out.println(konto);
Thread wplacacz = new Thread(() -> {
for(int i = 0 ; i < N; i++) {
konto.wplata(KWOTA);
}
});
Thread wyplacacz = new Thread(() -> {
for(int i = 0; i < N; i++) {
try {
konto.wyplata(KWOTA);
} catch (BrakSrodkow e) {
System.err.println(e.getMessage());
}
}
});
System.out.println("Uruchamiam wątki");
wplacacz.start();
wyplacacz.start();
System.out.println("Czekam na zakończenie");
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Wątki zakończone, konto na końcu:");
System.out.println(konto);
}
System.out.println("Czekam na zakończenie");
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Wątki zakończone, konto na końcu:");
System.out.println(konto);
}
}
......@@ -4,63 +4,63 @@ import java.io.IOException;
class WyplacanieBezOczekiwania {
static volatile boolean koniec = false;
static volatile boolean koniec = false;
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
try {
konto.wyplata(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
} catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW");
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
try {
konto.wyplata(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
} catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW");
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
wplacacz.start();
wyplacacz.start();
wplacacz.start();
wyplacacz.start();
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
System.err.println("INTERRUPTED");
}
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
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;
public class BrakSrodkow extends Exception {
private static final long serialVersionUID = 5262944731342409658L;
private static final long serialVersionUID = 5262944731342409658L;
public BrakSrodkow() {
super();
}
public BrakSrodkow() {
super();
}
public BrakSrodkow(String message) {
super(message);
}
public BrakSrodkow(String message) {
super(message);
}
}
package watki.gotowe.konta.v2_synchronizacja_metod;
class Konto {
private final int numer;
private int saldo;
private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
private final int numer;
private int saldo;
private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
public synchronized Osoba getWlasciciel() {
return wlasciciel;
}
public synchronized Osoba getWlasciciel() {
return wlasciciel;
}
public synchronized void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel;
}
public synchronized void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel;
}
public int getNumer() {
return numer;
}
public int getNumer() {
return numer;
}
public synchronized int getSaldo() {
return saldo;
}
public synchronized void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
saldo += kwota;
notify();
// System.out.println("I jeszcze coś robię");
// saldo --; // potrącić prowizję
// wątek obudzony z notify musi jeszcze poczekać, aż ja skończę tu robotę
// bo to jeszcze ja zajmuję sekcje "synchorized"
}
public synchronized int getSaldo() {
return saldo;
}
public synchronized void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
saldo += kwota;
notify();
// System.out.println("I jeszcze coś robię");
// saldo --; // potrącić prowizję
// wątek obudzony z notify musi jeszcze poczekać, aż ja skończę tu robotę
// bo to jeszcze ja zajmuję sekcje "synchorized"
}
public synchronized void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
saldo -= kwota;
}
public synchronized void wyplataCzekaj(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
try {
while(kwota > saldo) {
wait();
// po obudzeniu (notify) ten wątek na normalnych prawach
// czeka na dostęp do sekcji synchronizowanej
// 1) wątek, który zrobił notify, musi wyjść
// 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
// Również z tego powodu warunek oczekiwania należy sprawdzić ponownie po obudzeniu
// Standardowy zapis - pętla while.
}
saldo -= kwota;
notify(); // "budzenie kaskadowe"
} catch (InterruptedException e) {
// 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
// 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
// - w takiej sytuacji nie powinniśmy podejmować akcji zmieniających stan,
// ani nie powinnismy kontynuować czekania.
System.err.println(e);
}
}
public String toString() {
return "Konto nr " + getNumer() + ", saldo: " + getSaldo() + ", wł.: " + getWlasciciel();
}
public synchronized void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
saldo -= kwota;
}
public synchronized void wyplataCzekaj(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
try {
while(kwota > saldo) {
wait();
// po obudzeniu (notify) ten wątek na normalnych prawach
// czeka na dostęp do sekcji synchronizowanej
// 1) wątek, który zrobił notify, musi wyjść
// 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
// Również z tego powodu warunek oczekiwania należy sprawdzić ponownie po obudzeniu
// Standardowy zapis - pętla while.
}
saldo -= kwota;
notify(); // "budzenie kaskadowe"
} catch (InterruptedException e) {
// 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
// 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
// - w takiej sytuacji nie powinniśmy podejmować akcji zmieniających stan,
// ani nie powinnismy kontynuować czekania.
System.err.println(e);
}
}
public String toString() {
return "Konto nr " + getNumer() + ", saldo: " + getSaldo() + ", wł.: " + getWlasciciel();
}
}
package watki.gotowe.konta.v2_synchronizacja_metod;
class Konto_Niepoprawnie {
private final int numer;
private int saldo;
private Osoba wlasciciel;
public Konto_Niepoprawnie(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
private final int numer;
private int saldo;
private Osoba wlasciciel;
public Konto_Niepoprawnie(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
public synchronized Osoba getWlasciciel() {
return wlasciciel;
}
public synchronized Osoba getWlasciciel() {
return wlasciciel;
}
public synchronized void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel;
}
public synchronized void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel;
}
public int getNumer() {
return numer;
}
public int getNumer() {
return numer;
}
public synchronized int getSaldo() {
return saldo;
}
public synchronized void setSaldo(int saldo) {
this.saldo = saldo;
}
public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel;
}
public void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
this.setSaldo(this.getSaldo() + kwota);
// Nawet jeśli getter i setter są synchronizowane, to powyższy zapis jest niepoprawny
// bo to się tłumaczy na
public synchronized int getSaldo() {
return saldo;
}
public synchronized void setSaldo(int saldo) {
this.saldo = saldo;
}
public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel;
}
public void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
this.setSaldo(this.getSaldo() + kwota);
// Nawet jeśli getter i setter są synchronizowane, to powyższy zapis jest niepoprawny
// bo to się tłumaczy na
// int stareSaldo = this.getSaldo();
// int noweSaldo = stareSaldo + kwota;
// W TYM momencie inny wątek może też odczytać saldo, zmienić i zapisać
// 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 {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
this.setSaldo(this.getSaldo() - kwota);
}
public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
this.setSaldo(this.getSaldo() - kwota);
}
}
......@@ -4,63 +4,63 @@ import java.time.LocalDate;
import java.time.Period;
class Osoba {
private String imie, nazwisko;
private LocalDate dataUrodzenia;
public Osoba() {
}
Osoba(String imie, String nazwisko) {
this.imie = imie;
this.nazwisko = nazwisko;
}
private String imie, nazwisko;
private LocalDate dataUrodzenia;
public Osoba() {
}
Osoba(String imie, String nazwisko) {
this.imie = imie;
this.nazwisko = nazwisko;
}
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.setImie(imie);
this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia;
}
public Osoba(String imie, String nazwisko, String dataUrodzenia) {
// wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
}
public int obliczWiek() {
LocalDate dzisiaj = LocalDate.now();
Period wiek = Period.between(dataUrodzenia, dzisiaj);
return wiek.getYears();
}
@Override
public String toString() {
return imie + " " +nazwisko + " ur." + dataUrodzenia;
}
public String kimJestes() {
return "Jestem osobą";
}
public String getImie() {
return imie;
}
public String getNazwisko() {
return nazwisko;
}
public LocalDate getDataUrodzenia() {
return dataUrodzenia;
}
public void setImie(String imie) {
if(imie == null || imie.isEmpty()) {
throw new IllegalArgumentException("imię nie może być puste");
}
this.imie = imie;
}
public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.setImie(imie);
this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia;
}
public Osoba(String imie, String nazwisko, String dataUrodzenia) {
// wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
}
public int obliczWiek() {
LocalDate dzisiaj = LocalDate.now();
Period wiek = Period.between(dataUrodzenia, dzisiaj);
return wiek.getYears();
}
@Override
public String toString() {
return imie + " " +nazwisko + " ur." + dataUrodzenia;
}
public String kimJestes() {
return "Jestem osobą";
}
public String getImie() {
return imie;
}
public String getNazwisko() {
return nazwisko;
}
public LocalDate getDataUrodzenia() {
return dataUrodzenia;
}
public void setImie(String imie) {
if(imie == null || imie.isEmpty()) {
throw new IllegalArgumentException("imię nie może być puste");
}
this.imie = imie;
}
public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}
}
......@@ -4,45 +4,45 @@ import java.time.LocalDate;
class Przeploty {
public static void main(String[] args) {
final int N = 100_000;
final int KWOTA = 10;
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now());
Konto konto = new Konto(1, 1000_000, ala);
System.out.println(konto);
Thread wplacacz = new Thread(() -> {
for(int i = 0 ; i < N; i++) {
konto.wplata(KWOTA);
}
});
Thread wyplacacz = new Thread(() -> {
for(int i = 0; i < N; i++) {
try {
konto.wyplata(KWOTA);
} catch (BrakSrodkow e) {
System.err.println(e.getMessage());
}
}
});
System.out.println("Uruchamiam wątki");
wplacacz.start();
wyplacacz.start();
public static void main(String[] args) {
final int N = 100_000;
final int KWOTA = 10;
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now());
Konto konto = new Konto(1, 1000_000, ala);
System.out.println(konto);
Thread wplacacz = new Thread(() -> {
for(int i = 0 ; i < N; i++) {
konto.wplata(KWOTA);
}
});
Thread wyplacacz = new Thread(() -> {
for(int i = 0; i < N; i++) {
try {
konto.wyplata(KWOTA);
} catch (BrakSrodkow e) {
System.err.println(e.getMessage());
}
}
});
System.out.println("Uruchamiam wątki");
wplacacz.start();
wyplacacz.start();
System.out.println("Czekam na zakończenie");
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Wątki zakończone, konto na końcu:");
System.out.println(konto);
}
System.out.println("Czekam na zakończenie");
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Wątki zakończone, konto na końcu:");
System.out.println(konto);
}
}
......@@ -4,63 +4,63 @@ import java.io.IOException;
class WyplacanieBezOczekiwania {
static volatile boolean koniec = false;
static volatile boolean koniec = false;
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
try {
konto.wyplata(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
} catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW");
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
try {
konto.wyplata(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
} catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW");
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
wplacacz.start();
wyplacacz.start();
wplacacz.start();
wyplacacz.start();
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
System.err.println("INTERRUPTED");
}
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
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;
class WyplacanieZOczekiwaniem {
static volatile boolean koniec = false;
static volatile boolean koniec = false;
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wyplataCzekaj(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wyplataCzekaj(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
wplacacz.start();
wyplacacz.start();
wplacacz.start();
wyplacacz.start();
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
wplacacz.interrupt();
wyplacacz.interrupt();
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
wplacacz.interrupt();
wyplacacz.interrupt();
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
System.err.println("INTERRUPTED");
}
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
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;
public class BrakSrodkow extends Exception {
private static final long serialVersionUID = 5262944731342409658L;
private static final long serialVersionUID = 5262944731342409658L;
public BrakSrodkow() {
super();
}
public BrakSrodkow() {
super();
}
public BrakSrodkow(String message) {
super(message);
}
public BrakSrodkow(String message) {
super(message);
}
}
package watki.gotowe.konta.v3_synchronizacja_blokow;
class Konto {
private final int numer;
private int saldo;
private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
private final int numer;
private int saldo;
private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
public synchronized Osoba getWlasciciel() {
return wlasciciel;
}
public synchronized Osoba getWlasciciel() {
return wlasciciel;
}
public synchronized void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel;
}
public synchronized void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel;
}
public int getNumer() {
return numer;
}
public int getNumer() {
return numer;
}
public synchronized int getSaldo() {
return saldo;
}
public void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
synchronized(this) {
saldo += kwota;
this.notify();
}
}
public synchronized int getSaldo() {
return saldo;
}
public void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
synchronized(this) {
saldo += kwota;
this.notify();
}
}
public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
// 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.
synchronized(this) {
if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
saldo -= kwota;
}
}
public void wyplataCzekaj(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
try {
synchronized(this) {
while(kwota > saldo) {
this.wait();
}
saldo -= kwota;
this.notify();
}
} catch (InterruptedException e) {
System.err.println(e);
}
}
public String toString() {
return "Konto nr " + getNumer() + ", saldo: " + getSaldo() + ", wł.: " + getWlasciciel();
}
public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
// 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.
synchronized(this) {
if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
saldo -= kwota;
}
}
public void wyplataCzekaj(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
try {
synchronized(this) {
while(kwota > saldo) {
this.wait();
}
saldo -= kwota;
this.notify();
}
} catch (InterruptedException e) {
System.err.println(e);
}
}
public String toString() {
return "Konto nr " + getNumer() + ", saldo: " + getSaldo() + ", wł.: " + getWlasciciel();
}
}
......@@ -4,63 +4,63 @@ import java.time.LocalDate;
import java.time.Period;
class Osoba {
private String imie, nazwisko;
private LocalDate dataUrodzenia;
public Osoba() {
}
Osoba(String imie, String nazwisko) {
this.imie = imie;
this.nazwisko = nazwisko;
}
private String imie, nazwisko;
private LocalDate dataUrodzenia;
public Osoba() {
}
Osoba(String imie, String nazwisko) {
this.imie = imie;
this.nazwisko = nazwisko;
}
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.setImie(imie);
this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia;
}
public Osoba(String imie, String nazwisko, String dataUrodzenia) {
// wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
}
public int obliczWiek() {
LocalDate dzisiaj = LocalDate.now();
Period wiek = Period.between(dataUrodzenia, dzisiaj);
return wiek.getYears();
}
@Override
public String toString() {
return imie + " " +nazwisko + " ur." + dataUrodzenia;
}
public String kimJestes() {
return "Jestem osobą";
}
public String getImie() {
return imie;
}
public String getNazwisko() {
return nazwisko;
}
public LocalDate getDataUrodzenia() {
return dataUrodzenia;
}
public void setImie(String imie) {
if(imie == null || imie.isEmpty()) {
throw new IllegalArgumentException("imię nie może być puste");
}
this.imie = imie;
}
public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.setImie(imie);
this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia;
}
public Osoba(String imie, String nazwisko, String dataUrodzenia) {
// wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
}
public int obliczWiek() {
LocalDate dzisiaj = LocalDate.now();
Period wiek = Period.between(dataUrodzenia, dzisiaj);
return wiek.getYears();
}
@Override
public String toString() {
return imie + " " +nazwisko + " ur." + dataUrodzenia;
}
public String kimJestes() {
return "Jestem osobą";
}
public String getImie() {
return imie;
}
public String getNazwisko() {
return nazwisko;
}
public LocalDate getDataUrodzenia() {
return dataUrodzenia;
}
public void setImie(String imie) {
if(imie == null || imie.isEmpty()) {
throw new IllegalArgumentException("imię nie może być puste");
}
this.imie = imie;
}
public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}
}
......@@ -4,45 +4,45 @@ import java.time.LocalDate;
class Przeploty {
public static void main(String[] args) {
final int N = 100_000;
final int KWOTA = 10;
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now());
Konto konto = new Konto(1, 1000_000, ala);
System.out.println(konto);
Thread wplacacz = new Thread(() -> {
for(int i = 0 ; i < N; i++) {
konto.wplata(KWOTA);
}
});
Thread wyplacacz = new Thread(() -> {
for(int i = 0; i < N; i++) {
try {
konto.wyplata(KWOTA);
} catch (BrakSrodkow e) {
System.err.println(e.getMessage());
}
}
});
System.out.println("Uruchamiam wątki");
wplacacz.start();
wyplacacz.start();
public static void main(String[] args) {
final int N = 100_000;
final int KWOTA = 10;
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now());
Konto konto = new Konto(1, 1000_000, ala);
System.out.println(konto);
Thread wplacacz = new Thread(() -> {
for(int i = 0 ; i < N; i++) {
konto.wplata(KWOTA);
}
});
Thread wyplacacz = new Thread(() -> {
for(int i = 0; i < N; i++) {
try {
konto.wyplata(KWOTA);
} catch (BrakSrodkow e) {
System.err.println(e.getMessage());
}
}
});
System.out.println("Uruchamiam wątki");
wplacacz.start();
wyplacacz.start();
System.out.println("Czekam na zakończenie");
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Wątki zakończone, konto na końcu:");
System.out.println(konto);
}
System.out.println("Czekam na zakończenie");
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Wątki zakończone, konto na końcu:");
System.out.println(konto);
}
}
......@@ -4,63 +4,63 @@ import java.io.IOException;
class WyplacanieBezOczekiwania {
static volatile boolean koniec = false;
static volatile boolean koniec = false;
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
try {
konto.wyplata(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
} catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW");
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
try {
konto.wyplata(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
} catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW");
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
wplacacz.start();
wyplacacz.start();
wplacacz.start();
wyplacacz.start();
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
System.err.println("INTERRUPTED");
}
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
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;
class WyplacanieZOczekiwaniem {
static volatile boolean koniec = false;
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1500, ala);
System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wyplataCzekaj(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
wplacacz.start();
wyplacacz.start();
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
System.err.println("INTERRUPTED");
}
System.out.println("na końcu: " + konto);
}
static volatile boolean koniec = false;
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1500, ala);
System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wyplataCzekaj(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
wplacacz.start();
wyplacacz.start();
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
System.err.println("INTERRUPTED");
}
System.out.println("na końcu: " + konto);
}
}
package watki.gotowe.konta.v4_locki;
public class BrakSrodkow extends Exception {
private static final long serialVersionUID = 5262944731342409658L;
private static final long serialVersionUID = 5262944731342409658L;
public BrakSrodkow() {
super();
}
public BrakSrodkow() {
super();
}
public BrakSrodkow(String message) {
super(message);
}
public BrakSrodkow(String message) {
super(message);
}
}
......@@ -5,103 +5,102 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Konto {
private final Lock lock = new ReentrantLock();
private final Condition czekanieNaKase = lock.newCondition();
private final Lock lock = new ReentrantLock();
private final Condition czekanieNaKase = lock.newCondition();
// można tworzyć osobne condition związane z oczekiwaniem na różne warunki
private final Condition czekanieNaUdzielenieKredytu = lock.newCondition();
// można tworzyć osobne condition związane z oczekiwaniem na różne warunki
private final Condition czekanieNaUdzielenieKredytu = lock.newCondition();
private final int numer;
protected int saldo;
private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
public Osoba getWlasciciel() {
try {
lock.lock();
return wlasciciel;
} finally {
lock.unlock();
}
}
private final int numer;
protected int saldo;
private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
public Osoba getWlasciciel() {
try {
lock.lock();
return wlasciciel;
} finally {
lock.unlock();
}
}
public void setWlasciciel(Osoba wlasciciel) {
try {
lock.lock();
this.wlasciciel = wlasciciel;
} finally {
lock.unlock();
}
}
public void setWlasciciel(Osoba wlasciciel) {
try {
lock.lock();
this.wlasciciel = wlasciciel;
} finally {
lock.unlock();
}
}
public int getNumer() {
return numer;
}
public int getNumer() {
return numer;
}
public int getSaldo() {
lock.lock();
try {
return saldo;
} finally {
lock.unlock();
}
}
public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel;
}
public void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
lock.lock();
saldo += kwota;
czekanieNaKase.signal();
lock.unlock();
}
public int getSaldo() {
lock.lock();
try {
return saldo;
} finally {
lock.unlock();
}
}
public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel;
}
public void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
lock.lock();
saldo += kwota;
czekanieNaKase.signal();
lock.unlock();
}
public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
lock.lock();
try {
if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
saldo -= kwota;
} finally {
lock.unlock();
}
}
public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
lock.lock();
try {
if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
saldo -= kwota;
} finally {
lock.unlock();
}
}
public void wyplataCzekaj(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
lock.lock();
try {
while (kwota > saldo) {
czekanieNaKase.await();
}
saldo -= kwota;
czekanieNaKase.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void wyplataCzekaj(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
lock.lock();
try {
while (kwota > saldo) {
czekanieNaKase.await();
}
saldo -= kwota;
czekanieNaKase.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
......@@ -4,63 +4,63 @@ import java.time.LocalDate;
import java.time.Period;
class Osoba {
private String imie, nazwisko;
private LocalDate dataUrodzenia;
public Osoba() {
}
Osoba(String imie, String nazwisko) {
this.imie = imie;
this.nazwisko = nazwisko;
}
private String imie, nazwisko;
private LocalDate dataUrodzenia;
public Osoba() {
}
Osoba(String imie, String nazwisko) {
this.imie = imie;
this.nazwisko = nazwisko;
}
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.setImie(imie);
this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia;
}
public Osoba(String imie, String nazwisko, String dataUrodzenia) {
// wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
}
public int obliczWiek() {
LocalDate dzisiaj = LocalDate.now();
Period wiek = Period.between(dataUrodzenia, dzisiaj);
return wiek.getYears();
}
@Override
public String toString() {
return imie + " " +nazwisko + " ur." + dataUrodzenia;
}
public String kimJestes() {
return "Jestem osobą";
}
public String getImie() {
return imie;
}
public String getNazwisko() {
return nazwisko;
}
public LocalDate getDataUrodzenia() {
return dataUrodzenia;
}
public void setImie(String imie) {
if(imie == null || imie.isEmpty()) {
throw new IllegalArgumentException("imię nie może być puste");
}
this.imie = imie;
}
public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.setImie(imie);
this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia;
}
public Osoba(String imie, String nazwisko, String dataUrodzenia) {
// wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
}
public int obliczWiek() {
LocalDate dzisiaj = LocalDate.now();
Period wiek = Period.between(dataUrodzenia, dzisiaj);
return wiek.getYears();
}
@Override
public String toString() {
return imie + " " +nazwisko + " ur." + dataUrodzenia;
}
public String kimJestes() {
return "Jestem osobą";
}
public String getImie() {
return imie;
}
public String getNazwisko() {
return nazwisko;
}
public LocalDate getDataUrodzenia() {
return dataUrodzenia;
}
public void setImie(String imie) {
if(imie == null || imie.isEmpty()) {
throw new IllegalArgumentException("imię nie może być puste");
}
this.imie = imie;
}
public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}
}
......@@ -2,16 +2,16 @@ package watki.gotowe.konta.v4_locki;
public class Podklasa extends Konto {
public Podklasa(int numer, int saldo, Osoba wlasciciel) {
super(numer, saldo, wlasciciel);
}
public Podklasa(int numer, int saldo, Osoba wlasciciel) {
super(numer, saldo, wlasciciel);
}
public void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
saldo += kwota;
}
public void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
saldo += kwota;
}
}
......@@ -4,45 +4,45 @@ import java.time.LocalDate;
class Przeploty {
public static void main(String[] args) {
final int N = 100_000;
final int KWOTA = 10;
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now());
Konto konto = new Konto(1, 1000_000, ala);
System.out.println(konto);
Thread wplacacz = new Thread(() -> {
for(int i = 0 ; i < N; i++) {
konto.wplata(KWOTA);
}
});
Thread wyplacacz = new Thread(() -> {
for(int i = 0; i < N; i++) {
try {
konto.wyplata(KWOTA);
} catch (BrakSrodkow e) {
System.err.println(e.getMessage());
}
}
});
System.out.println("Uruchamiam wątki");
wplacacz.start();
wyplacacz.start();
public static void main(String[] args) {
final int N = 100_000;
final int KWOTA = 10;
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now());
Konto konto = new Konto(1, 1000_000, ala);
System.out.println(konto);
Thread wplacacz = new Thread(() -> {
for(int i = 0 ; i < N; i++) {
konto.wplata(KWOTA);
}
});
Thread wyplacacz = new Thread(() -> {
for(int i = 0; i < N; i++) {
try {
konto.wyplata(KWOTA);
} catch (BrakSrodkow e) {
System.err.println(e.getMessage());
}
}
});
System.out.println("Uruchamiam wątki");
wplacacz.start();
wyplacacz.start();
System.out.println("Czekam na zakończenie");
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Wątki zakończone, konto na końcu:");
System.out.println(konto);
}
System.out.println("Czekam na zakończenie");
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Wątki zakończone, konto na końcu:");
System.out.println(konto);
}
}
......@@ -4,63 +4,63 @@ import java.io.IOException;
class WyplacanieBezOczekiwania {
static volatile boolean koniec = false;
static volatile boolean koniec = false;
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
try {
konto.wyplata(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
} catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW");
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
try {
konto.wyplata(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
} catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW");
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
wplacacz.start();
wyplacacz.start();
wplacacz.start();
wyplacacz.start();
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
System.err.println("INTERRUPTED");
}
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
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;
class WyplacanieZOczekiwaniem {
static volatile boolean koniec = false;
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wyplataCzekaj(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
wplacacz.start();
wyplacacz.start();
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
System.err.println("INTERRUPTED");
}
System.out.println("na końcu: " + konto);
}
static volatile boolean koniec = false;
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wyplataCzekaj(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
wplacacz.start();
wyplacacz.start();
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
System.err.println("INTERRUPTED");
}
System.out.println("na końcu: " + konto);
}
}
package watki.gotowe.konta.v5_semafor;
public class BrakSrodkow extends Exception {
private static final long serialVersionUID = 5262944731342409658L;
private static final long serialVersionUID = 5262944731342409658L;
public BrakSrodkow() {
super();
}
public BrakSrodkow() {
super();
}
public BrakSrodkow(String message) {
super(message);
}
public BrakSrodkow(String message) {
super(message);
}
}
......@@ -8,95 +8,95 @@ import java.util.concurrent.Semaphore;
* ale w Javie nadają się tam, gdzie trzeba "liczyć zasoby" (zob. Afrykarium3).
*/
class Konto {
private final Semaphore mutex = new Semaphore(1);
private final Semaphore kasa = new Semaphore(0);
private int iluCzekaNaKase = 0;
private final Semaphore mutex = new Semaphore(1);
private final Semaphore kasa = new Semaphore(0);
private int iluCzekaNaKase = 0;
private final int numer;
protected int saldo;
private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
private final int numer;
protected int saldo;
private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
public Osoba getWlasciciel() {
return wlasciciel;
}
public Osoba getWlasciciel() {
return wlasciciel;
}
public void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel;
}
public void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel;
}
public int getNumer() {
return numer;
}
public int getNumer() {
return numer;
}
public int getSaldo() {
return saldo;
}
public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel;
}
public void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
try {
mutex.acquire();
saldo += kwota;
if(iluCzekaNaKase > 0) {
kasa.release();
} else {
mutex.release();
}
} catch (InterruptedException e) {
mutex.release();
}
}
public int getSaldo() {
return saldo;
}
public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel;
}
public void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
try {
mutex.acquire();
saldo += kwota;
if(iluCzekaNaKase > 0) {
kasa.release();
} else {
mutex.release();
}
} catch (InterruptedException e) {
mutex.release();
}
}
public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
try {
mutex.acquire();
if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
saldo -= kwota;
} catch (InterruptedException e) {
} finally {
mutex.release();
}
}
public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
try {
mutex.acquire();
if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
saldo -= kwota;
} catch (InterruptedException e) {
} finally {
mutex.release();
}
}
public void wyplataCzekaj(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
try {
mutex.acquire();
while (kwota > saldo) {
iluCzekaNaKase++;
mutex.release();
kasa.acquire();
iluCzekaNaKase--;
}
saldo -= kwota;
} catch (InterruptedException e) {
} finally {
mutex.release();
}
}
public void wyplataCzekaj(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
try {
mutex.acquire();
while (kwota > saldo) {
iluCzekaNaKase++;
mutex.release();
kasa.acquire();
iluCzekaNaKase--;
}
saldo -= kwota;
} catch (InterruptedException e) {
} finally {
mutex.release();
}
}
}
......@@ -4,63 +4,63 @@ import java.time.LocalDate;
import java.time.Period;
class Osoba {
private String imie, nazwisko;
private LocalDate dataUrodzenia;
public Osoba() {
}
Osoba(String imie, String nazwisko) {
this.imie = imie;
this.nazwisko = nazwisko;
}
private String imie, nazwisko;
private LocalDate dataUrodzenia;
public Osoba() {
}
Osoba(String imie, String nazwisko) {
this.imie = imie;
this.nazwisko = nazwisko;
}
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.setImie(imie);
this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia;
}
public Osoba(String imie, String nazwisko, String dataUrodzenia) {
// wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
}
public int obliczWiek() {
LocalDate dzisiaj = LocalDate.now();
Period wiek = Period.between(dataUrodzenia, dzisiaj);
return wiek.getYears();
}
@Override
public String toString() {
return imie + " " +nazwisko + " ur." + dataUrodzenia;
}
public String kimJestes() {
return "Jestem osobą";
}
public String getImie() {
return imie;
}
public String getNazwisko() {
return nazwisko;
}
public LocalDate getDataUrodzenia() {
return dataUrodzenia;
}
public void setImie(String imie) {
if(imie == null || imie.isEmpty()) {
throw new IllegalArgumentException("imię nie może być puste");
}
this.imie = imie;
}
public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.setImie(imie);
this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia;
}
public Osoba(String imie, String nazwisko, String dataUrodzenia) {
// wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
}
public int obliczWiek() {
LocalDate dzisiaj = LocalDate.now();
Period wiek = Period.between(dataUrodzenia, dzisiaj);
return wiek.getYears();
}
@Override
public String toString() {
return imie + " " +nazwisko + " ur." + dataUrodzenia;
}
public String kimJestes() {
return "Jestem osobą";
}
public String getImie() {
return imie;
}
public String getNazwisko() {
return nazwisko;
}
public LocalDate getDataUrodzenia() {
return dataUrodzenia;
}
public void setImie(String imie) {
if(imie == null || imie.isEmpty()) {
throw new IllegalArgumentException("imię nie może być puste");
}
this.imie = imie;
}
public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}
}
......@@ -2,16 +2,16 @@ package watki.gotowe.konta.v5_semafor;
public class Podklasa extends Konto {
public Podklasa(int numer, int saldo, Osoba wlasciciel) {
super(numer, saldo, wlasciciel);
}
public Podklasa(int numer, int saldo, Osoba wlasciciel) {
super(numer, saldo, wlasciciel);
}
public void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
saldo += kwota;
}
public void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
saldo += kwota;
}
}
......@@ -4,45 +4,45 @@ import java.time.LocalDate;
class Przeploty {
public static void main(String[] args) {
final int N = 100_000;
final int KWOTA = 10;
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now());
Konto konto = new Konto(1, 1000_000, ala);
System.out.println(konto);
Thread wplacacz = new Thread(() -> {
for(int i = 0 ; i < N; i++) {
konto.wplata(KWOTA);
}
});
Thread wyplacacz = new Thread(() -> {
for(int i = 0; i < N; i++) {
try {
konto.wyplata(KWOTA);
} catch (BrakSrodkow e) {
System.err.println(e.getMessage());
}
}
});
System.out.println("Uruchamiam wątki");
wplacacz.start();
wyplacacz.start();
public static void main(String[] args) {
final int N = 100_000;
final int KWOTA = 10;
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now());
Konto konto = new Konto(1, 1000_000, ala);
System.out.println(konto);
Thread wplacacz = new Thread(() -> {
for(int i = 0 ; i < N; i++) {
konto.wplata(KWOTA);
}
});
Thread wyplacacz = new Thread(() -> {
for(int i = 0; i < N; i++) {
try {
konto.wyplata(KWOTA);
} catch (BrakSrodkow e) {
System.err.println(e.getMessage());
}
}
});
System.out.println("Uruchamiam wątki");
wplacacz.start();
wyplacacz.start();
System.out.println("Czekam na zakończenie");
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Wątki zakończone, konto na końcu:");
System.out.println(konto);
}
System.out.println("Czekam na zakończenie");
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Wątki zakończone, konto na końcu:");
System.out.println(konto);
}
}
......@@ -4,63 +4,63 @@ import java.io.IOException;
class WyplacanieBezOczekiwania {
static volatile boolean koniec = false;
static volatile boolean koniec = false;
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
try {
konto.wyplata(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
} catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW");
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
try {
konto.wyplata(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
} catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW");
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
wplacacz.start();
wyplacacz.start();
wplacacz.start();
wyplacacz.start();
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
System.err.println("INTERRUPTED");
}
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
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;
class WyplacanieZOczekiwaniem {
static volatile boolean koniec = false;
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wyplataCzekaj(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
wplacacz.start();
wyplacacz.start();
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
System.err.println("INTERRUPTED");
}
System.out.println("na końcu: " + konto);
}
static volatile boolean koniec = false;
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wyplataCzekaj(100);
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
wplacacz.start();
wyplacacz.start();
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
System.err.println("INTERRUPTED");
}
System.out.println("na końcu: " + konto);
}
}
package watki.gotowe.konta.v6_synchronizacja_na_zwyklych_obiektach;
public class BrakSrodkow extends Exception {
private static final long serialVersionUID = 5262944731342409658L;
private static final long serialVersionUID = 5262944731342409658L;
public BrakSrodkow() {
super();
}
public BrakSrodkow() {
super();
}
public BrakSrodkow(String message) {
super(message);
}
public BrakSrodkow(String message) {
super(message);
}
}
......@@ -11,90 +11,90 @@ import java.util.List;
*/
class Konto {
private final int numer;
private int saldo;
private Osoba wlasciciel;
private List<String> wnioski = new ArrayList<>();
// te obiekty istnieją tylko po to, aby wątki mogły "na nich czekać"
private Object ochronaSalda = new Object();
private Object ochronaWnioskow = new Object();
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel;
}
public void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
synchronized(ochronaSalda) {
saldo += kwota;
ochronaSalda.notify();
}
}
private final int numer;
private int saldo;
private Osoba wlasciciel;
private List<String> wnioski = new ArrayList<>();
// te obiekty istnieją tylko po to, aby wątki mogły "na nich czekać"
private Object ochronaSalda = new Object();
private Object ochronaWnioskow = new Object();
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel;
}
public void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
synchronized(ochronaSalda) {
saldo += kwota;
ochronaSalda.notify();
}
}
public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
synchronized(ochronaSalda) {
if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
saldo -= kwota;
}
}
public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
synchronized(ochronaSalda) {
if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
saldo -= kwota;
}
}
public void wyplataCzekaj(int kwota) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
try {
synchronized(ochronaSalda) {
while(kwota > saldo) {
ochronaSalda.wait();
}
saldo -= kwota;
ochronaSalda.notify();
}
} catch (InterruptedException e) {
// Jeśli ktoś przerwie za pomocą interrupt(), tzn. "nie czekaj już, daj sobie spokój", wtedy rezygnuję z wykonania operacji biznesowej
}
}
public void wyplataCzekaj(int kwota) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
try {
synchronized(ochronaSalda) {
while(kwota > saldo) {
ochronaSalda.wait();
}
saldo -= kwota;
ochronaSalda.notify();
}
} catch (InterruptedException e) {
// Jeśli ktoś przerwie za pomocą interrupt(), tzn. "nie czekaj już, daj sobie spokój", wtedy rezygnuję z wykonania operacji biznesowej
}
}
public Osoba getWlasciciel() {
return wlasciciel;
}
public Osoba getWlasciciel() {
return wlasciciel;
}
public void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel;
}
public void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel;
}
public int getNumer() {
return numer;
}
public int getNumer() {
return numer;
}
public int getSaldo() {
synchronized(ochronaSalda) {
return saldo;
}
}
public void zlozWniosekKredytowy(int suma) {
synchronized(ochronaWnioskow) {
wnioski.add("Wniosek o " + suma);
}
}
public int getSaldo() {
synchronized(ochronaSalda) {
return saldo;
}
}
public void zlozWniosekKredytowy(int suma) {
synchronized(ochronaWnioskow) {
wnioski.add("Wniosek o " + suma);
}
}
}
......@@ -4,63 +4,63 @@ import java.time.LocalDate;
import java.time.Period;
class Osoba {
private String imie, nazwisko;
private LocalDate dataUrodzenia;
public Osoba() {
}
Osoba(String imie, String nazwisko) {
this.imie = imie;
this.nazwisko = nazwisko;
}
private String imie, nazwisko;
private LocalDate dataUrodzenia;
public Osoba() {
}
Osoba(String imie, String nazwisko) {
this.imie = imie;
this.nazwisko = nazwisko;
}
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.setImie(imie);
this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia;
}
public Osoba(String imie, String nazwisko, String dataUrodzenia) {
// wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
}
public int obliczWiek() {
LocalDate dzisiaj = LocalDate.now();
Period wiek = Period.between(dataUrodzenia, dzisiaj);
return wiek.getYears();
}
@Override
public String toString() {
return imie + " " +nazwisko + " ur." + dataUrodzenia;
}
public String kimJestes() {
return "Jestem osobą";
}
public String getImie() {
return imie;
}
public String getNazwisko() {
return nazwisko;
}
public LocalDate getDataUrodzenia() {
return dataUrodzenia;
}
public void setImie(String imie) {
if(imie == null || imie.isEmpty()) {
throw new IllegalArgumentException("imię nie może być puste");
}
this.imie = imie;
}
public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.setImie(imie);
this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia;
}
public Osoba(String imie, String nazwisko, String dataUrodzenia) {
// wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
}
public int obliczWiek() {
LocalDate dzisiaj = LocalDate.now();
Period wiek = Period.between(dataUrodzenia, dzisiaj);
return wiek.getYears();
}
@Override
public String toString() {
return imie + " " +nazwisko + " ur." + dataUrodzenia;
}
public String kimJestes() {
return "Jestem osobą";
}
public String getImie() {
return imie;
}
public String getNazwisko() {
return nazwisko;
}
public LocalDate getDataUrodzenia() {
return dataUrodzenia;
}
public void setImie(String imie) {
if(imie == null || imie.isEmpty()) {
throw new IllegalArgumentException("imię nie może być puste");
}
this.imie = imie;
}
public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}
}
......@@ -4,45 +4,45 @@ import java.time.LocalDate;
class Przeploty {
public static void main(String[] args) {
final int N = 100_000;
final int KWOTA = 10;
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now());
Konto konto = new Konto(1, 1000_000, ala);
System.out.println(konto);
Thread wplacacz = new Thread(() -> {
for(int i = 0 ; i < N; i++) {
konto.wplata(KWOTA);
}
});
Thread wyplacacz = new Thread(() -> {
for(int i = 0; i < N; i++) {
try {
konto.wyplata(KWOTA);
} catch (BrakSrodkow e) {
System.err.println(e.getMessage());
}
}
});
System.out.println("Uruchamiam wątki");
wplacacz.start();
wyplacacz.start();
public static void main(String[] args) {
final int N = 100_000;
final int KWOTA = 10;
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.now());
Konto konto = new Konto(1, 1000_000, ala);
System.out.println(konto);
Thread wplacacz = new Thread(() -> {
for(int i = 0 ; i < N; i++) {
konto.wplata(KWOTA);
}
});
Thread wyplacacz = new Thread(() -> {
for(int i = 0; i < N; i++) {
try {
konto.wyplata(KWOTA);
} catch (BrakSrodkow e) {
System.err.println(e.getMessage());
}
}
});
System.out.println("Uruchamiam wątki");
wplacacz.start();
wyplacacz.start();
System.out.println("Czekam na zakończenie");
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Wątki zakończone, konto na końcu:");
System.out.println(konto);
}
System.out.println("Czekam na zakończenie");
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Wątki zakończone, konto na końcu:");
System.out.println(konto);
}
}
......@@ -4,63 +4,63 @@ import java.io.IOException;
class WyplacanieBezOczekiwania {
static volatile boolean koniec = false;
static volatile boolean koniec = false;
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
try {
konto.wyplata(100);
} catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW");
}
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
try {
konto.wyplata(100);
} catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW");
}
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
wplacacz.start();
wyplacacz.start();
wplacacz.start();
wyplacacz.start();
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
System.err.println("INTERRUPTED");
}
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
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;
class WyplacanieZOczekiwaniem {
static volatile boolean koniec = false;
static volatile boolean koniec = false;
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
public static void main(String[] args) {
final Osoba ala = new Osoba("Ala", "Kowalska", "2001-01-01");
final Konto konto = new Konto(1, 1700, ala);
System.out.println("początek " + konto);
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
try {
konto.wyplataCzekaj(100);
} catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW");
}
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
Thread wplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
konto.wplata(1000);
System.out.println("wpłacacz: wpłaciłem 1000, saldo = " + konto.getSaldo());
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
}
}
}
});
Thread wyplacacz = new Thread(new Runnable() {
public void run() {
while (!koniec) {
try {
konto.wyplataCzekaj(100);
} catch (BrakSrodkow e) {
System.err.println("BRAK ŚRODKÓW");
}
System.out.println("wypłacacz: wypłaciłem 100, saldo = " + konto.getSaldo());
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
});
wplacacz.start();
wyplacacz.start();
wplacacz.start();
wyplacacz.start();
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
System.out.println("Wątki wystartowały");
System.out.println("Naciśnij enter aby zakończyć");
try {
System.in.read();
} catch (IOException e1) {
}
koniec = true;
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
System.err.println("INTERRUPTED");
}
try {
wplacacz.join();
wyplacacz.join();
} catch (InterruptedException e) {
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;
import java.util.concurrent.ThreadLocalRandom;
public class ForkJoin1_SumArray {
static class SumArray extends ForkJoinTask<Long> {
private Long result;
private byte[] array;
private int from, to;
public SumArray(byte[] array, int from, int to) {
this.array = array;
this.from = from;
this.to = to;
}
static class SumArray extends ForkJoinTask<Long> {
private Long result;
private byte[] array;
private int from, to;
public SumArray(byte[] array, int from, int to) {
this.array = array;
this.from = from;
this.to = to;
}
@Override
public Long getRawResult() {
return result;
}
@Override
public Long getRawResult() {
return result;
}
@Override
protected void setRawResult(Long value) {
this.result = value;
}
@Override
protected void setRawResult(Long value) {
this.result = value;
}
@Override
protected boolean exec() {
if(to - from == 1) {
this.setRawResult(Long.valueOf(array[from]));
} else {
int middle = (from + to) / 2;
SumArray left = new SumArray(array, from, middle);
SumArray right = new SumArray(array, middle, to);
left.fork();
right.fork();
try {
Long part1 = left.get();
Long part2 = right.get();
setRawResult(part1 + part2);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
setRawResult(0L);
}
}
return true;
}
}
@Override
protected boolean exec() {
if(to - from == 1) {
this.setRawResult(Long.valueOf(array[from]));
} else {
int middle = (from + to) / 2;
SumArray left = new SumArray(array, from, middle);
SumArray right = new SumArray(array, middle, to);
left.fork();
right.fork();
try {
Long part1 = left.get();
Long part2 = right.get();
setRawResult(part1 + part2);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
setRawResult(0L);
}
}
return true;
}
}
public static void main(String[] args) {
byte[] tab = new byte[160_000_000];
public static void main(String[] args) {
byte[] tab = new byte[160_000_000];
final ThreadLocalRandom random = ThreadLocalRandom.current();
System.out.println("Losowanie...");
for(int i = 0; i < tab.length; i++)
tab[i] = (byte)random.nextInt(256);
Long result;
System.out.println("\nLiczenie sekwencyjne:");
long start = System.currentTimeMillis();
result = sumaSekwencyjnie(tab);
long stop = System.currentTimeMillis();
System.out.println("Result = " + result + " , czas = " + (stop - start));
final ThreadLocalRandom random = ThreadLocalRandom.current();
System.out.println("Losowanie...");
for(int i = 0; i < tab.length; i++)
tab[i] = (byte)random.nextInt(256);
Long result;
System.out.println("\nLiczenie sekwencyjne:");
long start = System.currentTimeMillis();
result = sumaSekwencyjnie(tab);
long stop = System.currentTimeMillis();
System.out.println("Result = " + result + " , czas = " + (stop - start));
System.out.println("\nLiczenie fork/join:");
final ForkJoinPool pool = new ForkJoinPool(8);
SumArray task = new SumArray(tab, 0, tab.length);
System.out.println("Start");
start = System.currentTimeMillis();
result = pool.invoke(task);
stop = System.currentTimeMillis();
System.out.println("Result = " + result + " , czas = " + (stop - start));
}
System.out.println("\nLiczenie fork/join:");
final ForkJoinPool pool = new ForkJoinPool(8);
SumArray task = new SumArray(tab, 0, tab.length);
System.out.println("Start");
start = System.currentTimeMillis();
result = pool.invoke(task);
stop = System.currentTimeMillis();
System.out.println("Result = " + result + " , czas = " + (stop - start));
}
private static long sumaSekwencyjnie(byte[] tab, int from, int to) {
long suma = 0;
while(from < to)
suma += tab[from++];
return suma;
}
private static long sumaSekwencyjnie(byte[] tab) {
return sumaSekwencyjnie(tab, 0, tab.length);
}
private static long sumaSekwencyjnie(byte[] tab, int from, int to) {
long suma = 0;
while(from < to)
suma += tab[from++];
return suma;
}
private static long sumaSekwencyjnie(byte[] tab) {
return sumaSekwencyjnie(tab, 0, tab.length);
}
}
......@@ -6,88 +6,88 @@ import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.ThreadLocalRandom;
public class ForkJoin2_SumArray_Limit_Get {
static class SumArray extends ForkJoinTask<Long> {
private Long result;
private byte[] array;
private int from, to;
public SumArray(byte[] array, int from, int to) {
this.array = array;
this.from = from;
this.to = to;
}
static class SumArray extends ForkJoinTask<Long> {
private Long result;
private byte[] array;
private int from, to;
public SumArray(byte[] array, int from, int to) {
this.array = array;
this.from = from;
this.to = to;
}
@Override
public Long getRawResult() {
return result;
}
@Override
public Long getRawResult() {
return result;
}
@Override
protected void setRawResult(Long value) {
this.result = value;
}
@Override
protected void setRawResult(Long value) {
this.result = value;
}
@Override
protected boolean exec() {
if(to - from <= 10_000_000) {
Long x = sumaSekwencyjnie(array, from, to);
this.setRawResult(x);
} else {
int middle = (from + to) / 2;
SumArray left = new SumArray(array, from, middle);
SumArray right = new SumArray(array, middle, to);
left.fork();
right.fork();
try {
Long part1 = left.get();
Long part2 = right.get();
setRawResult(part1 + part2);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
setRawResult(0L);
return false;
}
}
return true;
}
}
@Override
protected boolean exec() {
if(to - from <= 10_000_000) {
Long x = sumaSekwencyjnie(array, from, to);
this.setRawResult(x);
} else {
int middle = (from + to) / 2;
SumArray left = new SumArray(array, from, middle);
SumArray right = new SumArray(array, middle, to);
left.fork();
right.fork();
try {
Long part1 = left.get();
Long part2 = right.get();
setRawResult(part1 + part2);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
setRawResult(0L);
return false;
}
}
return true;
}
}
public static void main(String[] args) {
byte[] tab = new byte[160_000_000];
public static void main(String[] args) {
byte[] tab = new byte[160_000_000];
final ThreadLocalRandom random = ThreadLocalRandom.current();
System.out.println("Losowanie...");
for(int i = 0; i < tab.length; i++)
tab[i] = (byte)random.nextInt(256);
Long result;
final ForkJoinPool pool = new ForkJoinPool(8);
System.out.println("\nLiczenie sekwencyjne:");
long start = System.currentTimeMillis();
result = sumaSekwencyjnie(tab);
long stop = System.currentTimeMillis();
System.out.println("Result = " + result + " , czas = " + (stop - start));
final ThreadLocalRandom random = ThreadLocalRandom.current();
System.out.println("Losowanie...");
for(int i = 0; i < tab.length; i++)
tab[i] = (byte)random.nextInt(256);
Long result;
final ForkJoinPool pool = new ForkJoinPool(8);
System.out.println("\nLiczenie sekwencyjne:");
long start = System.currentTimeMillis();
result = sumaSekwencyjnie(tab);
long stop = System.currentTimeMillis();
System.out.println("Result = " + result + " , czas = " + (stop - start));
System.out.println("\nLiczenie fork/join:");
SumArray task = new SumArray(tab, 0, tab.length);
System.out.println("Start");
start = System.currentTimeMillis();
result = pool.invoke(task);
stop = System.currentTimeMillis();
System.out.println("Result = " + result + " , czas = " + (stop - start));
}
System.out.println("\nLiczenie fork/join:");
SumArray task = new SumArray(tab, 0, tab.length);
System.out.println("Start");
start = System.currentTimeMillis();
result = pool.invoke(task);
stop = System.currentTimeMillis();
System.out.println("Result = " + result + " , czas = " + (stop - start));
}
private static Long sumaSekwencyjnie(byte[] tab, int from, int to) {
long suma = 0;
while(from < to)
suma += tab[from++];
return suma;
}
private static Long sumaSekwencyjnie(byte[] tab) {
return sumaSekwencyjnie(tab, 0, tab.length);
}
private static Long sumaSekwencyjnie(byte[] tab, int from, int to) {
long suma = 0;
while(from < to)
suma += tab[from++];
return suma;
}
private static Long sumaSekwencyjnie(byte[] tab) {
return sumaSekwencyjnie(tab, 0, tab.length);
}
}
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