From 9144eeb06764eb75e397be767fc28bb11378a401 Mon Sep 17 00:00:00 2001 From: Yan Wittmann <2121578@stud.hs-mannheim.de> Date: Thu, 1 Dec 2022 17:16:43 +0100 Subject: [PATCH] Finished writing ThreadsafeSimplifiedList --- src/main/java/io/dama/ffi/hoh/Main.java | 11 ++- .../ffi/hoh/ThreadsafeSimplifiedList.java | 98 +++++++++++++++---- 2 files changed, 86 insertions(+), 23 deletions(-) diff --git a/src/main/java/io/dama/ffi/hoh/Main.java b/src/main/java/io/dama/ffi/hoh/Main.java index 82db479..2327f5a 100644 --- a/src/main/java/io/dama/ffi/hoh/Main.java +++ b/src/main/java/io/dama/ffi/hoh/Main.java @@ -8,10 +8,14 @@ public class Main { var sum = 0; for (var i = start; i < end; i++) { sum += list.get(i); + if (i % 250 == 0) { + System.out.println("Progress in " + Thread.currentThread().getName() + ": " + sum + " " + i); + } } if (sum != expected) { - System.out.println("Fehler in " - + Thread.currentThread().getName() + ": " + sum); + System.err.println("Fehler in " + Thread.currentThread().getName() + ": " + sum); + } else { + System.out.println("Ok in " + Thread.currentThread().getName() + ": " + sum); } }; } @@ -21,6 +25,9 @@ public class Main { for (int i = 0; i < 5000; i++) { list.add(i); } + + System.out.println("Liste: " + list); + var thread0 = new Thread(sliceSum(0, 1250, 780625)); var thread1 = new Thread(sliceSum(1250, 2500, 2343125)); var thread2 = new Thread(sliceSum(2500, 3750, 3905625)); diff --git a/src/main/java/io/dama/ffi/hoh/ThreadsafeSimplifiedList.java b/src/main/java/io/dama/ffi/hoh/ThreadsafeSimplifiedList.java index bbc53aa..1063b0c 100644 --- a/src/main/java/io/dama/ffi/hoh/ThreadsafeSimplifiedList.java +++ b/src/main/java/io/dama/ffi/hoh/ThreadsafeSimplifiedList.java @@ -1,5 +1,8 @@ package io.dama.ffi.hoh; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + public class ThreadsafeSimplifiedList implements SimplifiedList { private Node first; @@ -7,6 +10,7 @@ public class ThreadsafeSimplifiedList implements SimplifiedList { private U element; private Node prev; private Node next; + private final Lock lock = new ReentrantLock(); private Node(U element, Node prev, Node next) { super(); @@ -14,6 +18,18 @@ public class ThreadsafeSimplifiedList implements SimplifiedList { this.prev = prev; this.next = next; } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("'").append(this.element).append("'"); + var node = this; + while (node.next != null) { + node = node.next; + builder.append(" -> '").append(node.element).append("'"); + } + return builder.toString(); + } } public ThreadsafeSimplifiedList() { @@ -28,31 +44,54 @@ public class ThreadsafeSimplifiedList implements SimplifiedList { * @return the element at the specified position in this list */ @Override - public synchronized T get(int index) { - var ptr = this.first; - for (var j = 0; j < index; j++) { - ptr = ptr.next; + public T get(int index) { + Node ptr = this.first; + + ptr.lock.lock(); + try { + for (var j = 0; j < index; j++) { + ptr.next.lock.lock(); + ptr = ptr.next; + ptr.prev.lock.unlock(); + } + + return delay(ptr.element); + } finally { + ptr.lock.unlock(); + if (ptr.prev != null && ptr.prev.lock.tryLock()) { + ptr.prev.lock.unlock(); + } } - return delay(ptr.element); } /** * Appends the specified element to the end of this list. There are no * limitations on what elements may be added to this list. - * + * * @param element element to be appended to this list * @return true * @see java.util.Collection#add(Object) - * */ @Override - public synchronized boolean add(T element) { + public boolean add(T element) { if (this.first != null) { var ptr = this.first; - while (ptr.next != null) { - ptr = ptr.next; + + ptr.lock.lock(); + try { + while (ptr.next != null) { + ptr.next.lock.lock(); + ptr = ptr.next; + ptr.prev.lock.unlock(); + } + + ptr.next = new Node<>(element, ptr, null); + } finally { + ptr.lock.unlock(); + if (ptr.prev != null && ptr.prev.lock.tryLock()) { + ptr.prev.lock.unlock(); + } } - ptr.next = new Node<>(element, ptr, null); } else { this.first = new Node<>(element, null, null); } @@ -62,29 +101,46 @@ public class ThreadsafeSimplifiedList implements SimplifiedList { /** * Replaces the element at the specified position in this list with the * specified element. - * + * * @param index index of the element to replace * @param element element to be stored at the specified position * @return the element previously at the specified position */ @Override - public synchronized T set(int index, T element) { - var ptr = this.first; - for (var j = 0; j < index; j++) { - ptr = ptr.next; + public T set(int index, T element) { + Node ptr = this.first; + + ptr.lock.lock(); + try { + for (var j = 0; j < index; j++) { + ptr.next.lock.lock(); + ptr = ptr.next; + ptr.prev.lock.unlock(); + } + + var prevElement = ptr.element; + ptr.element = element; + return prevElement; + } finally { + ptr.lock.unlock(); + if (ptr.prev != null && ptr.prev.lock.tryLock()) { + ptr.prev.lock.unlock(); + } } - var prevElement = ptr.element; - ptr.element = element; - return prevElement; } /** * Returns true if this list contains no elements. - * + * * @return true if this list contains no elements */ @Override - public synchronized boolean isEmpty() { + public boolean isEmpty() { return this.first == null; } + + @Override + public String toString() { + return this.first != null ? "[" + this.first + "]" : "[]"; + } }