diff --git a/u04-1/README.md b/u04-1/README.md index 2c54536..904de75 100644 --- a/u04-1/README.md +++ b/u04-1/README.md @@ -1,3 +1,5 @@ +# Problem 4.1: Data exchange point between two threads + Implement a class `Exchanger` that is usable to exchange an object of type `T` between exactly two threads: diff --git a/u05-3/README.md b/u05-3/README.md new file mode 100644 index 0000000..711a103 --- /dev/null +++ b/u05-3/README.md @@ -0,0 +1,8 @@ +# Problem 5.3: Implement a semaphore in Java + +Implement a Java class `Semaphor` with methods `p()` and `v() `as decribed in the lecture. Your class +should work for any number of threads using the same semaphore concurrently. Test your class using +the class `DiningPhilosophersWithForkAccessSema` (on the server in the source code folder +for chapter 4) by replacing all uses of `java.util.concurrent.Semaphore` by uses of your own +`Semaphor` class – the program's behavior should still be correct (though not identical, since the +output of the program is not determinate). \ No newline at end of file diff --git a/u05-4/README.md b/u05-4/README.md new file mode 100644 index 0000000..fd2837a --- /dev/null +++ b/u05-4/README.md @@ -0,0 +1,7 @@ +# Problem 5.4: Work queue of limited length using semaphores + +Implement the work queue of limited length from problem 4.2 using semaphores as the only +synchronization mechanism, i.e. without `synchronized` blocks or methods (and, consequentially, +not `wait()` or `notify()`). Test your program with your own semaphore class from problem 5.3 and +with `java.util.concurrent.Semaphore`. Make sure not to use busy waiting: If a thread has +to wait, use semaphore operations for this. \ No newline at end of file diff --git a/u06-1/README.md b/u06-1/README.md new file mode 100644 index 0000000..0548bca --- /dev/null +++ b/u06-1/README.md @@ -0,0 +1,21 @@ +# Problem 6.1: Barrier without semaphore + +Implement a class `Barrier` that realizes a barrier similar to the **`CyclicBarrier`** mentioned on +slide 4-50 (your barrier does not have to be reusable); barriers are also described in the book by +Gleim/Schüle in section 3.2.7 (in German). Don't use semaphores, but only `synchronized`, `wait()` +and `notify/All()`. Your class should look about as follows: + +```java +class Barrier { + // … + public Barrier(int nThreads){ … } + // nThreads: Number of threads using this barrier + public int await() throws InterruptedException { … } + // Cross the barrier, possibly waiting before doing this + // Return value: Position of this thread when arriving at the barrier +} +``` + +Test your barrier with class `BarrierTest` in the source code folder on th server. In the program's +output, all `a()` invocations must appear before all `b()` invocations `Barrier` if your barrier is +correct. \ No newline at end of file diff --git a/u06-3/README.md b/u06-3/README.md new file mode 100644 index 0000000..395a51e --- /dev/null +++ b/u06-3/README.md @@ -0,0 +1,9 @@ +# Problem 6.3: Dining philosophers with globally uniform acquisition order + +As mentioned in the lecture, one possible strategy to avoid a deadlock is to acquire all resources in the +same, globally uniform order, so that it cannot happen that e.g. thread A first acquires resource 1 and +then resource 2, while thread B acquires the same resouces in a different order (first 2 and then 1). + +Implement a deadlock-free solution to the "dining philosophers" problem from the lecture using this +strategy by defining a globally uniform acquisition order for the fork semaphores; an additional +semaphore as in the lecture will no longer be necessary then. \ No newline at end of file diff --git a/u06-4/README.md b/u06-4/README.md new file mode 100644 index 0000000..496d018 --- /dev/null +++ b/u06-4/README.md @@ -0,0 +1,18 @@ +# Problem 6.4: Implement AtomicXXX.updateAndGet + +On slide 4-46 two implementations for the modification of an `AtomicXXX` object were presented: A +loop with a `compareAndSet()` operation and the more abstract and more general +`updateAndGet()` operation. Implement your own `updateAndGet()` method for the +`AtomicCounter` class on slide 4-46. Use `compareAndSet()` for this. Use the following interface +as the parameter type for the lambda expression: + +```java +interface IntUnaryOperator { + int applyAsInt(int x); +} +``` + +What condition must hold for the behavior of the code passed to `updateAndGet()`? + +Test your class with the class `AtomicCounterTest` to be found in the source code folder on he +server. Its output must be `100000000`. \ No newline at end of file diff --git a/u06-5/README.md b/u06-5/README.md new file mode 100644 index 0000000..7c4b0ff --- /dev/null +++ b/u06-5/README.md @@ -0,0 +1,20 @@ +# Problem 6.5: Implement a nonblocking spin lock + +Spin locks are often used in code close to the hardware (e.g. in operating system kernels) to lock short +critical sections where the overhead of blocking and later unblocking the thread would cost more time +than the thread normally has to wait until entering the section. Instead of that, a spin lock contains a +busy waitig loop that repeats ("spins round and round") until it succeeds to acquire the lock. + +Implement a spin lock as a Java class with the following structure and test it using the `SpinLockTest` +class in the source code folder on the server: + +```java +public class SpinLock { + // ... + public void lock() { + // ... + } + public boolean unlock() { // returns whether the lock had indeed been acquired by current thread + // ... + } +} \ No newline at end of file diff --git a/u07-1/README.md b/u07-1/README.md new file mode 100644 index 0000000..b0605d7 --- /dev/null +++ b/u07-1/README.md @@ -0,0 +1,17 @@ +# Problem 7.1: Parallel prime number test using tasks and `Executor` + +Implement a simple prime number test, first sequentially and then using concurrent tasks by means of +the Java `Executor` framework. Your program should test all numbers *n* between 2 and 100.000 for +primality by simply checking all numbers *d* from 2 to *n* whether *d* divides *n* without a remainder. (Of +course there are much more efficient primality tests, but the goal here is not efficient primality tests, +but simply generating some computation load.) As its result, your program should print the number of +prime numbers found by all tasks (the correct result is 9592). + +Divide the work into 100 tasks, each of them testing the next 1000 numbers. To simulate occasional +blocking due to I/O activity, make each task invoke `Thread.sleep()` after checking half of its +numbers, with the sleep time chosen randomly between 1 and 100 ms (the sample solution to problem +4.2 shows an example for this). + +Use a `newFixedThreadPool()`, initialized with the number of available core (obtainable using +`Runtime.getRuntime().availableProcessors()`). Experiment with a higher number of +threads or with a `newCachedThreadPool`, too. \ No newline at end of file