add assignment readmes
This commit is contained in:
parent
8c63bec955
commit
636efbe8b3
|
@ -1,3 +1,5 @@
|
|||
# Problem 4.1: Data exchange point between two threads
|
||||
|
||||
Implement a class `Exchanger<T>` that is usable to exchange an object
|
||||
of type `T` between exactly two threads:
|
||||
|
||||
|
|
|
@ -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).
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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`.
|
|
@ -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
|
||||
// ...
|
||||
}
|
||||
}
|
|
@ -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.
|
Loading…
Reference in New Issue