diff --git a/src/pp.07.01.synchronizedWrapper/justfile b/src/pp.07.01.synchronizedWrapper/justfile
new file mode 100644
index 0000000..6ca7111
--- /dev/null
+++ b/src/pp.07.01.synchronizedWrapper/justfile
@@ -0,0 +1,18 @@
+# Justfile (https://just.systems/) for starting Maven standard targets
+
+default: clean compile package
+
+exec class args: compile
+ mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}}
+# exec class args:
+# java -cp target/app.jar {{class}} {{args}}
+clean:
+ mvn clean
+compile:
+ mvn compile
+test: compile
+ mvn test
+javadoc:
+ mvn javadoc:javadoc
+package:
+ mvn package
diff --git a/src/pp.07.01.synchronizedWrapper/pom.xml b/src/pp.07.01.synchronizedWrapper/pom.xml
new file mode 100644
index 0000000..8e3a167
--- /dev/null
+++ b/src/pp.07.01.synchronizedWrapper/pom.xml
@@ -0,0 +1,60 @@
+
+ 4.0.0
+ pp
+ pp.07.01.synchronizedWrapper
+ 1.0-SNAPSHOT
+ jar
+
+
+ 10
+ UTF-8
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ 5.10.0
+ test
+
+
+ org.projectlombok
+ lombok
+ 1.18.30
+ provided
+
+
+ net.jcip
+ jcip-annotations
+ 1.0
+ provided
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.9.0
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 3.1.0
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.5.0
+
+ private
+ en_US
+
+
+
+
+
diff --git a/src/pp.07.01.synchronizedWrapper/src/main/java/pp/SynchWrapper.java b/src/pp.07.01.synchronizedWrapper/src/main/java/pp/SynchWrapper.java
new file mode 100644
index 0000000..fd52b0d
--- /dev/null
+++ b/src/pp.07.01.synchronizedWrapper/src/main/java/pp/SynchWrapper.java
@@ -0,0 +1,16 @@
+package pp;
+
+import java.util.List;
+
+public class SynchWrapper {
+ private final List decorated;
+
+ public static List synchronizedList(List list) {
+ return (List) new SynchWrapper<>(list);
+ }
+
+ private SynchWrapper(List list) {
+ this.decorated = list;
+ }
+
+}
diff --git a/src/pp.07.01.synchronizedWrapper_solution/justfile b/src/pp.07.01.synchronizedWrapper_solution/justfile
new file mode 100644
index 0000000..6ca7111
--- /dev/null
+++ b/src/pp.07.01.synchronizedWrapper_solution/justfile
@@ -0,0 +1,18 @@
+# Justfile (https://just.systems/) for starting Maven standard targets
+
+default: clean compile package
+
+exec class args: compile
+ mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}}
+# exec class args:
+# java -cp target/app.jar {{class}} {{args}}
+clean:
+ mvn clean
+compile:
+ mvn compile
+test: compile
+ mvn test
+javadoc:
+ mvn javadoc:javadoc
+package:
+ mvn package
diff --git a/src/pp.07.01.synchronizedWrapper_solution/pom.xml b/src/pp.07.01.synchronizedWrapper_solution/pom.xml
new file mode 100644
index 0000000..38607cf
--- /dev/null
+++ b/src/pp.07.01.synchronizedWrapper_solution/pom.xml
@@ -0,0 +1,59 @@
+
+ 4.0.0
+ pp
+ pp.07.01.synchronizedWrapper_solution
+ 1.0-SNAPSHOT
+ jar
+
+
+ 10
+ UTF-8
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ 5.10.0
+ test
+
+
+ org.projectlombok
+ lombok
+ edge-SNAPSHOT
+
+
+ net.jcip
+ jcip-annotations
+ 1.0
+ provided
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.9.0
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 3.1.0
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.5.0
+
+ private
+ en_US
+
+
+
+
+
diff --git a/src/pp.07.01.synchronizedWrapper_solution/src/main/java/pp/SynchWrapper.java b/src/pp.07.01.synchronizedWrapper_solution/src/main/java/pp/SynchWrapper.java
new file mode 100644
index 0000000..ecc3052
--- /dev/null
+++ b/src/pp.07.01.synchronizedWrapper_solution/src/main/java/pp/SynchWrapper.java
@@ -0,0 +1,134 @@
+package pp;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+public class SynchWrapper implements List {
+ private final List decorated;
+
+ public static List synchronizedList(List list) {
+ return new SynchWrapper<>(list);
+ }
+
+ private SynchWrapper(List list) {
+ this.decorated = list;
+ }
+
+ @Override
+ public synchronized int size() {
+ return this.decorated.size();
+ }
+
+ @Override
+ public synchronized boolean isEmpty() {
+ return this.decorated.isEmpty();
+ }
+
+ @Override
+ public synchronized boolean contains(Object o) {
+ return this.decorated.contains(o);
+ }
+
+ @Override
+ public synchronized Iterator iterator() {
+ return this.decorated.iterator();
+ }
+
+ @Override
+ public synchronized Object[] toArray() {
+ return this.decorated.toArray();
+ }
+
+ @Override
+ public synchronized T[] toArray(T[] a) {
+ return this.decorated.toArray(a);
+ }
+
+ @Override
+ public synchronized boolean add(T e) {
+ return this.decorated.add(e);
+ }
+
+ @Override
+ public synchronized boolean remove(Object o) {
+ return this.decorated.remove(o);
+ }
+
+ @Override
+ public synchronized boolean containsAll(Collection> c) {
+ return this.decorated.containsAll(c);
+ }
+
+ @Override
+ public synchronized boolean addAll(Collection extends T> c) {
+ return this.decorated.addAll(c);
+ }
+
+ @Override
+ public synchronized boolean addAll(int index, Collection extends T> c) {
+ return this.decorated.addAll(index, c);
+ }
+
+ @Override
+ public synchronized boolean removeAll(Collection> c) {
+ return this.decorated.removeAll(c);
+ }
+
+ @Override
+ public synchronized boolean retainAll(Collection> c) {
+ return this.decorated.retainAll(c);
+ }
+
+ @Override
+ public synchronized void clear() {
+ this.decorated.clear();
+ }
+
+ @Override
+ public synchronized T get(int index) {
+ return this.decorated.get(index);
+ }
+
+ @Override
+ public synchronized T set(int index, T element) {
+ return this.decorated.set(index, element);
+ }
+
+ @Override
+ public synchronized void add(int index, T element) {
+ this.decorated.add(index, element);
+ }
+
+ @Override
+ public synchronized T remove(int index) {
+ return this.decorated.remove(index);
+ }
+
+ @Override
+ public synchronized int indexOf(Object o) {
+ return this.decorated.indexOf(o);
+ }
+
+ @Override
+ public synchronized int lastIndexOf(Object o) {
+ return this.decorated.lastIndexOf(o);
+ }
+
+ @Override
+ public synchronized ListIterator listIterator() {
+ return this.decorated.listIterator();
+ }
+
+ @Override
+ public synchronized ListIterator listIterator(int index) {
+ return this.decorated.listIterator(index);
+ }
+
+ @Override
+ public synchronized List subList(int fromIndex, int toIndex) {
+ return this.decorated.subList(fromIndex, toIndex);
+ }
+
+}
diff --git a/src/pp.07.01.synchronizedWrapper_solution/src/main/java/pp/SynchWrapperLombok.java b/src/pp.07.01.synchronizedWrapper_solution/src/main/java/pp/SynchWrapperLombok.java
new file mode 100644
index 0000000..b5b20da
--- /dev/null
+++ b/src/pp.07.01.synchronizedWrapper_solution/src/main/java/pp/SynchWrapperLombok.java
@@ -0,0 +1,159 @@
+package pp;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import lombok.Synchronized;
+
+public class SynchWrapperLombok implements List {
+ private final List decorated;
+
+ public static List synchronizedList(List list) {
+ return new SynchWrapperLombok<>(list);
+ }
+
+ private SynchWrapperLombok(List list) {
+ this.decorated = list;
+ }
+
+ @Override
+ @Synchronized
+ public int size() {
+ return this.decorated.size();
+ }
+
+ @Override
+ @Synchronized
+ public boolean isEmpty() {
+ return this.decorated.isEmpty();
+ }
+
+ @Override
+ @Synchronized
+ public boolean contains(Object o) {
+ return this.decorated.contains(o);
+ }
+
+ @Override
+ @Synchronized
+ public Iterator iterator() {
+ return this.decorated.iterator();
+ }
+
+ @Override
+ @Synchronized
+ public Object[] toArray() {
+ return this.decorated.toArray();
+ }
+
+ @Override
+ @Synchronized
+ public T[] toArray(T[] a) {
+ return this.decorated.toArray(a);
+ }
+
+ @Override
+ @Synchronized
+ public boolean add(T e) {
+ return this.decorated.add(e);
+ }
+
+ @Override
+ @Synchronized
+ public boolean remove(Object o) {
+ return this.decorated.remove(o);
+ }
+
+ @Override
+ @Synchronized
+ public boolean containsAll(Collection> c) {
+ return this.decorated.containsAll(c);
+ }
+
+ @Override
+ @Synchronized
+ public boolean addAll(Collection extends T> c) {
+ return this.decorated.addAll(c);
+ }
+
+ @Override
+ @Synchronized
+ public boolean addAll(int index, Collection extends T> c) {
+ return this.decorated.addAll(index, c);
+ }
+
+ @Override
+ @Synchronized
+ public boolean removeAll(Collection> c) {
+ return this.decorated.removeAll(c);
+ }
+
+ @Override
+ @Synchronized
+ public boolean retainAll(Collection> c) {
+ return this.decorated.retainAll(c);
+ }
+
+ @Override
+ @Synchronized
+ public void clear() {
+ this.decorated.clear();
+ }
+
+ @Override
+ @Synchronized
+ public T get(int index) {
+ return this.decorated.get(index);
+ }
+
+ @Override
+ @Synchronized
+ public T set(int index, T element) {
+ return this.decorated.set(index, element);
+ }
+
+ @Override
+ @Synchronized
+ public void add(int index, T element) {
+ this.decorated.add(index, element);
+ }
+
+ @Override
+ @Synchronized
+ public T remove(int index) {
+ return this.decorated.remove(index);
+ }
+
+ @Override
+ @Synchronized
+ public int indexOf(Object o) {
+ return this.decorated.indexOf(o);
+ }
+
+ @Override
+ @Synchronized
+ public int lastIndexOf(Object o) {
+ return this.decorated.lastIndexOf(o);
+ }
+
+ @Override
+ @Synchronized
+ public ListIterator listIterator() {
+ return this.decorated.listIterator();
+ }
+
+ @Override
+ @Synchronized
+ public ListIterator listIterator(int index) {
+ return this.decorated.listIterator(index);
+ }
+
+ @Override
+ @Synchronized
+ public List subList(int fromIndex, int toIndex) {
+ return this.decorated.subList(fromIndex, toIndex);
+ }
+
+}
diff --git a/src/pp.07.01.synchronizedWrapper_solution/src/main/java/pp/SynchWrapperRW.java b/src/pp.07.01.synchronizedWrapper_solution/src/main/java/pp/SynchWrapperRW.java
new file mode 100644
index 0000000..c298bd6
--- /dev/null
+++ b/src/pp.07.01.synchronizedWrapper_solution/src/main/java/pp/SynchWrapperRW.java
@@ -0,0 +1,258 @@
+package pp;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+public class SynchWrapperRW implements List {
+ private final List decorated;
+ private final ReadWriteLock lock;
+ private final Lock rLock;
+ private final Lock wLock;
+
+ public static List synchronizedList(List list) {
+ return new SynchWrapperRW<>(list);
+ }
+
+ private SynchWrapperRW(List list) {
+ this.decorated = list;
+ this.lock = new ReentrantReadWriteLock();
+ this.rLock = this.lock.readLock();
+ this.wLock = this.lock.writeLock();
+ }
+
+ @Override
+ public int size() {
+ this.rLock.lock();
+ try {
+ return this.decorated.size();
+ } finally {
+ this.rLock.unlock();
+ }
+ }
+
+ @Override
+ public boolean isEmpty() {
+ this.rLock.lock();
+ try {
+ return this.decorated.isEmpty();
+ } finally {
+ this.rLock.unlock();
+ }
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ this.rLock.lock();
+ try {
+ return this.decorated.contains(o);
+ } finally {
+ this.rLock.unlock();
+ }
+ }
+
+ @Override
+ public Iterator iterator() {
+ this.rLock.lock();
+ try {
+ return this.decorated.iterator();
+ } finally {
+ this.rLock.unlock();
+ }
+ }
+
+ @Override
+ public Object[] toArray() {
+ this.rLock.lock();
+ try {
+ return this.decorated.toArray();
+ } finally {
+ this.rLock.unlock();
+ }
+ }
+
+ @Override
+ public T[] toArray(T[] a) {
+ this.rLock.lock();
+ try {
+ return this.decorated.toArray(a);
+ } finally {
+ this.rLock.unlock();
+ }
+ }
+
+ @Override
+ public boolean add(T e) {
+ this.wLock.lock();
+ try {
+ return this.decorated.add(e);
+ } finally {
+ this.wLock.unlock();
+ }
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ this.wLock.lock();
+ try {
+ return this.decorated.remove(o);
+ } finally {
+ this.wLock.unlock();
+ }
+ }
+
+ @Override
+ public boolean containsAll(Collection> c) {
+ this.rLock.lock();
+ try {
+ return this.decorated.containsAll(c);
+ } finally {
+ this.rLock.unlock();
+ }
+ }
+
+ @Override
+ public boolean addAll(Collection extends T> c) {
+ this.wLock.lock();
+ try {
+ return this.decorated.addAll(c);
+ } finally {
+ this.wLock.unlock();
+ }
+ }
+
+ @Override
+ public boolean addAll(int index, Collection extends T> c) {
+ this.wLock.lock();
+ try {
+ return this.decorated.addAll(index, c);
+ } finally {
+ this.wLock.unlock();
+ }
+ }
+
+ @Override
+ public boolean removeAll(Collection> c) {
+ this.wLock.lock();
+ try {
+ return this.decorated.removeAll(c);
+ } finally {
+ this.wLock.unlock();
+ }
+ }
+
+ @Override
+ public boolean retainAll(Collection> c) {
+ this.wLock.lock();
+ try {
+ return this.decorated.retainAll(c);
+ } finally {
+ this.wLock.unlock();
+ }
+ }
+
+ @Override
+ public void clear() {
+ this.wLock.lock();
+ try {
+ this.decorated.clear();
+ } finally {
+ this.wLock.unlock();
+ }
+ }
+
+ @Override
+ public T get(int index) {
+ this.rLock.lock();
+ try {
+ return this.decorated.get(index);
+ } finally {
+ this.rLock.unlock();
+ }
+ }
+
+ @Override
+ public T set(int index, T element) {
+ this.wLock.lock();
+ try {
+ return this.decorated.set(index, element);
+ } finally {
+ this.wLock.unlock();
+ }
+ }
+
+ @Override
+ public void add(int index, T element) {
+ this.wLock.lock();
+ try {
+ this.decorated.add(index, element);
+ } finally {
+ this.wLock.unlock();
+ }
+ }
+
+ @Override
+ public T remove(int index) {
+ this.wLock.lock();
+ try {
+ return this.decorated.remove(index);
+ } finally {
+ this.wLock.unlock();
+ }
+ }
+
+ @Override
+ public int indexOf(Object o) {
+ this.rLock.lock();
+ try {
+ return this.decorated.indexOf(o);
+ } finally {
+ this.rLock.unlock();
+ }
+ }
+
+ @Override
+ public int lastIndexOf(Object o) {
+ this.rLock.lock();
+ try {
+ return this.decorated.lastIndexOf(o);
+ } finally {
+ this.rLock.unlock();
+ }
+ }
+
+ @Override
+ public ListIterator listIterator() {
+ this.rLock.lock();
+ try {
+ return this.decorated.listIterator();
+ } finally {
+ this.rLock.unlock();
+ }
+ }
+
+ @Override
+ public ListIterator listIterator(int index) {
+ this.rLock.lock();
+ try {
+ return this.decorated.listIterator(index);
+ } finally {
+ this.rLock.unlock();
+ }
+ }
+
+ @Override
+ public List subList(int fromIndex, int toIndex) {
+ this.rLock.lock();
+ try {
+ return this.decorated.subList(fromIndex, toIndex);
+ } finally {
+ this.rLock.unlock();
+ }
+ }
+
+}
diff --git a/src/pp.07.01.synchronizedWrapper_solution/src/main/java/pp/SynchWrapperRWLombok.java b/src/pp.07.01.synchronizedWrapper_solution/src/main/java/pp/SynchWrapperRWLombok.java
new file mode 100644
index 0000000..a9cb602
--- /dev/null
+++ b/src/pp.07.01.synchronizedWrapper_solution/src/main/java/pp/SynchWrapperRWLombok.java
@@ -0,0 +1,162 @@
+package pp;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import lombok.Locked;
+
+public class SynchWrapperRWLombok implements List {
+ private final List decorated;
+
+ public static List synchronizedList(List list) {
+ return new SynchWrapperRWLombok<>(list);
+ }
+
+ private SynchWrapperRWLombok(List list) {
+ this.decorated = list;
+ }
+
+ @Override
+ @Locked.Read
+ public int size() {
+ return this.decorated.size();
+ }
+
+ @Override
+ @Locked.Read
+ public boolean isEmpty() {
+ return this.decorated.isEmpty();
+ }
+
+ @Override
+ @Locked.Read
+ public boolean contains(Object o) {
+ return this.decorated.contains(o);
+ }
+
+ @Override
+ @Locked.Read
+ public Iterator iterator() {
+ return this.decorated.iterator();
+ }
+
+ @Override
+ @Locked.Read
+ public Object[] toArray() {
+ return this.decorated.toArray();
+ }
+
+ @Override
+ @Locked.Read
+ public T[] toArray(T[] a) {
+ return this.decorated.toArray(a);
+ }
+
+ @Override
+ @Locked.Write
+ public boolean add(T e) {
+ return this.decorated.add(e);
+ }
+
+ @Override
+ @Locked.Write
+ public boolean remove(Object o) {
+ return this.decorated.remove(o);
+ }
+
+ @Override
+ @Locked.Read
+ public boolean containsAll(Collection> c) {
+ return this.decorated.containsAll(c);
+ }
+
+ @Override
+ @Locked.Write
+ public boolean addAll(Collection extends T> c) {
+ return this.decorated.addAll(c);
+ }
+
+ @Override
+ @Locked.Write
+ public boolean addAll(int index, Collection extends T> c) {
+ return this.decorated.addAll(index, c);
+ }
+
+ @Override
+ @Locked.Write
+ public boolean removeAll(Collection> c) {
+ return this.decorated.removeAll(c);
+ }
+
+ @Override
+ @Locked.Write
+ public boolean retainAll(Collection> c) {
+ return this.decorated.retainAll(c);
+ }
+
+ @Override
+ @Locked.Write
+ public void clear() {
+ this.decorated.clear();
+ }
+
+ @Override
+ @Locked.Read
+ public T get(int index) {
+ return this.decorated.get(index);
+ }
+
+ @Override
+ @Locked.Write
+ public T set(int index, T element) {
+ return this.decorated.set(index, element);
+ }
+
+ @Override
+ @Locked.Write
+ public void add(int index, T element) {
+ this.decorated.add(index, element);
+ }
+
+ @Override
+ @Locked.Write
+ public T remove(int index) {
+ return this.decorated.remove(index);
+ }
+
+ @Override
+ @Locked.Read
+ public int indexOf(Object o) {
+ return this.decorated.indexOf(o);
+ }
+
+ @Override
+ @Locked.Read
+ public int lastIndexOf(Object o) {
+ return this.decorated.lastIndexOf(o);
+ }
+
+ @Override
+ @Locked.Read
+ public ListIterator listIterator() {
+ return this.decorated.listIterator();
+ }
+
+ @Override
+ @Locked.Read
+ public ListIterator listIterator(int index) {
+ return this.decorated.listIterator(index);
+ }
+
+ @Override
+ @Locked.Read
+ public List subList(int fromIndex, int toIndex) {
+ return this.decorated.subList(fromIndex, toIndex);
+ }
+
+}
diff --git a/src/pp.07.01.synchronizedWrapper_solution/src/test/java/pp/Tests.java b/src/pp.07.01.synchronizedWrapper_solution/src/test/java/pp/Tests.java
new file mode 100644
index 0000000..a971fae
--- /dev/null
+++ b/src/pp.07.01.synchronizedWrapper_solution/src/test/java/pp/Tests.java
@@ -0,0 +1,55 @@
+package pp;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class Tests {
+ private final static int SIZE = 10000;
+
+ static void testAdd(List l) {
+ var t1 = new Thread(() -> {
+ for (var i = 0; i < SIZE; i++) {
+ l.add(Integer.valueOf(i));
+ }
+ });
+ var t2 = new Thread(() -> {
+ for (var i = 0; i < SIZE; i++) {
+ l.add(Integer.valueOf(i));
+ }
+ });
+ t1.start();
+ t2.start();
+ try {
+ t1.join();
+ t2.join();
+ assertEquals(l.size(), SIZE * 2);
+ } catch (InterruptedException e) {
+ fail("Interrupt");
+ }
+ }
+
+ @Test
+ void testWrappedListSynchronizedAdd() {
+ testAdd(SynchWrapper.synchronizedList(new ArrayList()));
+ }
+
+ @Test
+ void testWrappedListReadWriteLockAdd() {
+ testAdd(SynchWrapperRW.synchronizedList(new ArrayList()));
+ }
+
+ @Test
+ void testWrappedListLombokLockAdd() {
+ testAdd(SynchWrapperLombok.synchronizedList(new ArrayList()));
+ }
+
+ @Test
+ void testWrappedListReadWriteiLombokLockAdd() {
+ testAdd(SynchWrapperRWLombok.synchronizedList(new ArrayList()));
+ }
+
+}
diff --git a/src/pp.07.02.Collections/justfile b/src/pp.07.02.Collections/justfile
new file mode 100644
index 0000000..6ca7111
--- /dev/null
+++ b/src/pp.07.02.Collections/justfile
@@ -0,0 +1,18 @@
+# Justfile (https://just.systems/) for starting Maven standard targets
+
+default: clean compile package
+
+exec class args: compile
+ mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}}
+# exec class args:
+# java -cp target/app.jar {{class}} {{args}}
+clean:
+ mvn clean
+compile:
+ mvn compile
+test: compile
+ mvn test
+javadoc:
+ mvn javadoc:javadoc
+package:
+ mvn package
diff --git a/src/pp.07.02.Collections/pom.xml b/src/pp.07.02.Collections/pom.xml
new file mode 100644
index 0000000..4c440b6
--- /dev/null
+++ b/src/pp.07.02.Collections/pom.xml
@@ -0,0 +1,60 @@
+
+ 4.0.0
+ pp
+ pp.07.02.Collections
+ 1.0-SNAPSHOT
+ jar
+
+
+ 10
+ UTF-8
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ 5.10.0
+ test
+
+
+ org.projectlombok
+ lombok
+ 1.18.30
+ provided
+
+
+ net.jcip
+ jcip-annotations
+ 1.0
+ provided
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.9.0
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 3.1.0
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.5.0
+
+ private
+ en_US
+
+
+
+
+
diff --git a/src/pp.07.02.Collections/src/main/java/pp/ExperimentVector.java b/src/pp.07.02.Collections/src/main/java/pp/ExperimentVector.java
new file mode 100644
index 0000000..fabf4c2
--- /dev/null
+++ b/src/pp.07.02.Collections/src/main/java/pp/ExperimentVector.java
@@ -0,0 +1,48 @@
+package pp;
+
+import java.util.Vector;
+
+class ExperimentVector {
+ Integer countA;
+ Integer countB;
+ Vector list;
+
+ void work(int size) throws InterruptedException {
+ this.countA = 0;
+ this.countB = 0;
+ this.list = new Vector<>();
+ var t1 = new Thread(() -> {
+ for (var i = 0; i < size; i++) {
+ this.list.add(1);
+ }
+ });
+ var t2 = new Thread(() -> {
+ for (var i = 0; i < size; i++) {
+ this.list.add(1);
+ }
+ });
+ var t3 = new Thread(() -> {
+ for (var i = 0; i < (size * 2); i++) {
+ this.countA += this.list.get(i);
+ }
+ });
+ var t4 = new Thread(() -> {
+ for (var i = (size * 2) - 1; i >= 0; i--) {
+ this.countB += this.list.get(i);
+ }
+ });
+ var now = System.currentTimeMillis();
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+ t3.start();
+ t4.start();
+ t3.join();
+ t4.join();
+ System.out.printf("Lauf %s, i=%d, Zeitdauer: %dms (%s)\n",
+ (this.countA.equals(this.countB)) ? "ok" : "fehlerhaft", size,
+ System.currentTimeMillis() - now, "Vector");
+ }
+
+}
diff --git a/src/pp.07.02.Collections_solution/justfile b/src/pp.07.02.Collections_solution/justfile
new file mode 100644
index 0000000..6ca7111
--- /dev/null
+++ b/src/pp.07.02.Collections_solution/justfile
@@ -0,0 +1,18 @@
+# Justfile (https://just.systems/) for starting Maven standard targets
+
+default: clean compile package
+
+exec class args: compile
+ mvn exec:java -Dexec.args="{{args}}" -Dexec.mainClass={{class}}
+# exec class args:
+# java -cp target/app.jar {{class}} {{args}}
+clean:
+ mvn clean
+compile:
+ mvn compile
+test: compile
+ mvn test
+javadoc:
+ mvn javadoc:javadoc
+package:
+ mvn package
diff --git a/src/pp.07.02.Collections_solution/pom.xml b/src/pp.07.02.Collections_solution/pom.xml
new file mode 100644
index 0000000..892cfe6
--- /dev/null
+++ b/src/pp.07.02.Collections_solution/pom.xml
@@ -0,0 +1,60 @@
+
+ 4.0.0
+ pp
+ pp.07.02.Collections_solution
+ 1.0-SNAPSHOT
+ jar
+
+
+ 10
+ UTF-8
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ 5.10.0
+ test
+
+
+ org.projectlombok
+ lombok
+ 1.18.30
+ provided
+
+
+ net.jcip
+ jcip-annotations
+ 1.0
+ provided
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.0.0
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.9.0
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 3.1.0
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.5.0
+
+ private
+ en_US
+
+
+
+
+
diff --git a/src/pp.07.02.Collections_solution/src/main/java/pp/ExperimentArrayList.java b/src/pp.07.02.Collections_solution/src/main/java/pp/ExperimentArrayList.java
new file mode 100644
index 0000000..25b5479
--- /dev/null
+++ b/src/pp.07.02.Collections_solution/src/main/java/pp/ExperimentArrayList.java
@@ -0,0 +1,57 @@
+package pp;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class ExperimentArrayList {
+ Integer countA;
+ Integer countB;
+ List list;
+
+ void work(int size) throws InterruptedException {
+ this.countA = 0;
+ this.countB = 0;
+ this.list = new ArrayList<>();
+ var t1 = new Thread(() -> {
+ for (var i = 0; i < size; i++) {
+ synchronized (this.list) {
+ this.list.add(1);
+ }
+ }
+ });
+ var t2 = new Thread(() -> {
+ for (var i = 0; i < size; i++) {
+ synchronized (this.list) {
+ this.list.add(1);
+ }
+ }
+ });
+ var t3 = new Thread(() -> {
+ for (var i = 0; i < (size * 2); i++) {
+ synchronized (this.list) {
+ this.countA += this.list.get(i);
+ }
+ }
+ });
+ var t4 = new Thread(() -> {
+ for (var i = (size * 2) - 1; i >= 0; i--) {
+ synchronized (this.list) {
+ this.countB += this.list.get(i);
+ }
+ }
+ });
+ var now = System.currentTimeMillis();
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+ t3.start();
+ t4.start();
+ t3.join();
+ t4.join();
+ System.out.printf("Lauf %s, i=%d, Zeitdauer: %dms (%s)\n",
+ (this.countA.equals(this.countB)) ? "ok" : "fehlerhaft", size,
+ System.currentTimeMillis() - now, "ArrayList");
+ }
+
+}
diff --git a/src/pp.07.02.Collections_solution/src/main/java/pp/ExperimentLinkedList.java b/src/pp.07.02.Collections_solution/src/main/java/pp/ExperimentLinkedList.java
new file mode 100644
index 0000000..73d9292
--- /dev/null
+++ b/src/pp.07.02.Collections_solution/src/main/java/pp/ExperimentLinkedList.java
@@ -0,0 +1,57 @@
+package pp;
+
+import java.util.LinkedList;
+import java.util.List;
+
+class ExperimentLinkedList {
+ Integer countA;
+ Integer countB;
+ List list;
+
+ void work(int size) throws InterruptedException {
+ this.countA = 0;
+ this.countB = 0;
+ this.list = new LinkedList<>();
+ var t1 = new Thread(() -> {
+ for (var i = 0; i < size; i++) {
+ synchronized (this.list) {
+ this.list.add(1);
+ }
+ }
+ });
+ var t2 = new Thread(() -> {
+ for (var i = 0; i < size; i++) {
+ synchronized (this.list) {
+ this.list.add(1);
+ }
+ }
+ });
+ var t3 = new Thread(() -> {
+ for (var i = 0; i < (size * 2); i++) {
+ synchronized (this.list) {
+ this.countA += this.list.get(i);
+ }
+ }
+ });
+ var t4 = new Thread(() -> {
+ for (var i = (size * 2) - 1; i >= 0; i--) {
+ synchronized (this.list) {
+ this.countB += this.list.get(i);
+ }
+ }
+ });
+ var now = System.currentTimeMillis();
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+ t3.start();
+ t4.start();
+ t3.join();
+ t4.join();
+ System.out.printf("Lauf %s, i=%d, Zeitdauer: %dms (%s)\n",
+ (this.countA.equals(this.countB)) ? "ok" : "fehlerhaft", size,
+ System.currentTimeMillis() - now, "LinkedList");
+ }
+
+}
diff --git a/src/pp.07.02.Collections_solution/src/main/java/pp/ExperimentSynchedArrayList.java b/src/pp.07.02.Collections_solution/src/main/java/pp/ExperimentSynchedArrayList.java
new file mode 100644
index 0000000..241f1d4
--- /dev/null
+++ b/src/pp.07.02.Collections_solution/src/main/java/pp/ExperimentSynchedArrayList.java
@@ -0,0 +1,50 @@
+package pp;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+class ExperimentSynchedArrayList {
+ Integer countA;
+ Integer countB;
+ List list;
+
+ void work(int size) throws InterruptedException {
+ this.countA = 0;
+ this.countB = 0;
+ this.list = Collections.synchronizedList(new ArrayList<>());
+ var t1 = new Thread(() -> {
+ for (var i = 0; i < size; i++) {
+ this.list.add(1);
+ }
+ });
+ var t2 = new Thread(() -> {
+ for (var i = 0; i < size; i++) {
+ this.list.add(1);
+ }
+ });
+ var t3 = new Thread(() -> {
+ for (var i = 0; i < (size * 2); i++) {
+ this.countA += this.list.get(i);
+ }
+ });
+ var t4 = new Thread(() -> {
+ for (var i = (size * 2) - 1; i >= 0; i--) {
+ this.countB += this.list.get(i);
+ }
+ });
+ var now = System.currentTimeMillis();
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+ t3.start();
+ t4.start();
+ t3.join();
+ t4.join();
+ System.out.printf("Lauf %s, i=%d, Zeitdauer: %dms (%s)\n",
+ (this.countA.equals(this.countB)) ? "ok" : "fehlerhaft", size,
+ System.currentTimeMillis() - now, "SynchedArrayList");
+ }
+
+}
diff --git a/src/pp.07.02.Collections_solution/src/main/java/pp/ExperimentSynchedLinkedList.java b/src/pp.07.02.Collections_solution/src/main/java/pp/ExperimentSynchedLinkedList.java
new file mode 100644
index 0000000..cd9c7a8
--- /dev/null
+++ b/src/pp.07.02.Collections_solution/src/main/java/pp/ExperimentSynchedLinkedList.java
@@ -0,0 +1,50 @@
+package pp;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+class ExperimentSynchedLinkedList {
+ Integer countA;
+ Integer countB;
+ List list;
+
+ void work(int size) throws InterruptedException {
+ this.countA = 0;
+ this.countB = 0;
+ this.list = Collections.synchronizedList(new LinkedList<>());
+ var t1 = new Thread(() -> {
+ for (var i = 0; i < size; i++) {
+ this.list.add(1);
+ }
+ });
+ var t2 = new Thread(() -> {
+ for (var i = 0; i < size; i++) {
+ this.list.add(1);
+ }
+ });
+ var t3 = new Thread(() -> {
+ for (var i = 0; i < (size * 2); i++) {
+ this.countA += this.list.get(i);
+ }
+ });
+ var t4 = new Thread(() -> {
+ for (var i = (size * 2) - 1; i >= 0; i--) {
+ this.countB += this.list.get(i);
+ }
+ });
+ var now = System.currentTimeMillis();
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+ t3.start();
+ t4.start();
+ t3.join();
+ t4.join();
+ System.out.printf("Lauf %s, i=%d, Zeitdauer: %dms (%s)\n",
+ (this.countA.equals(this.countB)) ? "ok" : "fehlerhaft", size,
+ System.currentTimeMillis() - now, "SynchedLinkedList");
+ }
+
+}
diff --git a/src/pp.07.02.Collections_solution/src/main/java/pp/ExperimentSynchedLinkedListRO.java b/src/pp.07.02.Collections_solution/src/main/java/pp/ExperimentSynchedLinkedListRO.java
new file mode 100644
index 0000000..ac7e722
--- /dev/null
+++ b/src/pp.07.02.Collections_solution/src/main/java/pp/ExperimentSynchedLinkedListRO.java
@@ -0,0 +1,55 @@
+package pp;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+class ExperimentSynchedLinkedListRO {
+ Integer countA;
+ Integer countB;
+ List list;
+ List listSynch;
+ List listRO;
+
+ void work(int size) throws InterruptedException {
+ this.countA = 0;
+ this.countB = 0;
+ this.list = new LinkedList<>();
+ this.listSynch = Collections.synchronizedList(this.list);
+ this.listRO = Collections.unmodifiableList(this.list);
+
+ var t1 = new Thread(() -> {
+ for (var i = 0; i < size; i++) {
+ this.listSynch.add(1);
+ }
+ });
+ var t2 = new Thread(() -> {
+ for (var i = 0; i < size; i++) {
+ this.listSynch.add(1);
+ }
+ });
+ var t3 = new Thread(() -> {
+ for (var i = 0; i < (size * 2); i++) {
+ this.countA += this.listRO.get(i);
+ }
+ });
+ var t4 = new Thread(() -> {
+ for (var i = (size * 2) - 1; i >= 0; i--) {
+ this.countB += this.listRO.get(i);
+ }
+ });
+ var now = System.currentTimeMillis();
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+ t3.start();
+ t4.start();
+ t3.join();
+ t4.join();
+ System.out.printf("Lauf %s, i=%d, Zeitdauer: %dms (%s)\n",
+ (this.countA.equals(this.countB)) ? "ok" : "fehlerhaft", size,
+ System.currentTimeMillis() - now, "SynchedLinkedListRO");
+ }
+
+}
diff --git a/src/pp.07.02.Collections_solution/src/main/java/pp/ExperimentVector.java b/src/pp.07.02.Collections_solution/src/main/java/pp/ExperimentVector.java
new file mode 100644
index 0000000..fabf4c2
--- /dev/null
+++ b/src/pp.07.02.Collections_solution/src/main/java/pp/ExperimentVector.java
@@ -0,0 +1,48 @@
+package pp;
+
+import java.util.Vector;
+
+class ExperimentVector {
+ Integer countA;
+ Integer countB;
+ Vector list;
+
+ void work(int size) throws InterruptedException {
+ this.countA = 0;
+ this.countB = 0;
+ this.list = new Vector<>();
+ var t1 = new Thread(() -> {
+ for (var i = 0; i < size; i++) {
+ this.list.add(1);
+ }
+ });
+ var t2 = new Thread(() -> {
+ for (var i = 0; i < size; i++) {
+ this.list.add(1);
+ }
+ });
+ var t3 = new Thread(() -> {
+ for (var i = 0; i < (size * 2); i++) {
+ this.countA += this.list.get(i);
+ }
+ });
+ var t4 = new Thread(() -> {
+ for (var i = (size * 2) - 1; i >= 0; i--) {
+ this.countB += this.list.get(i);
+ }
+ });
+ var now = System.currentTimeMillis();
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+ t3.start();
+ t4.start();
+ t3.join();
+ t4.join();
+ System.out.printf("Lauf %s, i=%d, Zeitdauer: %dms (%s)\n",
+ (this.countA.equals(this.countB)) ? "ok" : "fehlerhaft", size,
+ System.currentTimeMillis() - now, "Vector");
+ }
+
+}
diff --git a/src/pp.07.02.Collections_solution/src/main/java/pp/Main.java b/src/pp.07.02.Collections_solution/src/main/java/pp/Main.java
new file mode 100644
index 0000000..7cc4c6e
--- /dev/null
+++ b/src/pp.07.02.Collections_solution/src/main/java/pp/Main.java
@@ -0,0 +1,15 @@
+package pp;
+
+public class Main {
+
+ public static void main(String... args) throws InterruptedException {
+ for (var i = 100; i <= 100000; i *= 10) {
+ (new ExperimentVector()).work(i);
+ (new ExperimentArrayList()).work(i);
+ (new ExperimentLinkedList()).work(i);
+ (new ExperimentSynchedArrayList()).work(i);
+ (new ExperimentSynchedLinkedList()).work(i);
+ (new ExperimentSynchedLinkedListRO()).work(i);
+ }
+ }
+}