• Keine Ergebnisse gefunden

Design Patterns & Concurrency

N/A
N/A
Protected

Academic year: 2022

Aktie "Design Patterns & Concurrency"

Copied!
24
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Sebastian Graf & Oliver Haase

Design Patterns & Concurrency

1

Thursday, April 28, 2011

(2)

Content today

1.Deadlocks

2.Explicit and Intrinsic Locks 3.Happens-Before in the JVM 4.Publication

5.Open Part

(3)

But before…

3

public class MutableLong private long value;

public long get() { return value; }

public void set(long value) { this.value = value; } }

public class MutableInt private int value;

public int get() { return value; }

public void set(int value) { this.value = value; } }

Thursday, April 28, 2011

(4)

Recap

Visibility

‣ Publishing & Escaping

Locking

‣ Cancelation of Threads

(5)

Deadlock

5

public class LeftRightDeadlock {

private final Object left = new Object();

private final Object right = new Object();

public void leftRight() { synchronized (left) {

synchronized (right) { doSomething();

} }

}

public void rightLeft() { synchronized (right) {

synchronized (left) { doSomethingElse();

} }

} }

Thursday, April 28, 2011

(6)

Deadlock

A program will be free of deadlocks if all locks are

acquired in one defined fixed global order.

(7)

Deadlock free?

7

public void work(final Object source, final Object target) {

synchronized (source) {

synchronized (target) {

moveStuff(source, target);

}

}

}

/** doing something */

protected abstract void moveStuff(final Object source,

final Object target);

Thursday, April 28, 2011

(8)

Deadlock secure

private static final Object tieLock = new Object();

public void work(final Object source, final Object target) { int fromHash = System.identityHashCode(source);

int toHash = System.identityHashCode(target);

if (fromHash < toHash) {

synchronized (source) {

synchronized (target) {

moveStuff(source, target);

} }

} else if (fromHash > toHash) { synchronized (target) {

synchronized (source) {

moveStuff(source, target);

} }

} else {

synchronized (tieLock) {

synchronized (source) {

synchronized (target) {

moveStuff(source, target);

} }

} }

protected abstract moveStuff(final Object source, final Object target);

}

(9)

Resource-bound deadlocks

9

public class ThreadDeadlock {

ExecutorService exec = Executors.newSingleThreadExecutor();

public class RenderPageTask implements Callable<String> { public String call() throws Exception {

Future<String> header, footer;

header = exec.submit(new LoadFileTask("header.html"));

footer = exec.submit(new LoadFileTask("footer.html"));

String page = renderBody();

// Will deadlock -- task waiting for result of subtask return header.get() + page + footer.get();

} }

}

Thursday, April 28, 2011

(10)

What to do if deadlock happens?

(11)

When a lock is held…

‣ …check if it is really necessary.

‣ …refer to a global fixed order (and document it).

‣ …do not call alien methods.

‣ …use open calls.

…cancel it after a given amount of time (tryLock)

11

Thursday, April 28, 2011

(12)

Explicit & Intrinsic Locking

public interface Lock { void lock();

void lockInterruptibly() throws InterruptedException;

boolean tryLock();

boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException;

void unlock();

...

}

(13)

TryLock

13

public boolean work(final Object source, final Object target, long timeout) { long fixedDelay = getFixedDelayComponentNanos(timeout, unit);

long randMod = getRandomDelayModulusNanos(timeout, unit);

long stopTime = System.nanoTime() + unit.toNanos(timeout);

while (true) {

if (source.lock.tryLock()) { try {

if (target.lock.tryLock()) { try {

moveStuff(source,target);

return true;

} finally {

target.lock.unlock();

} }

} finally {

source.lock.unlock();

} }

if (System.nanoTime() < stopTime) return false;

NANOSECONDS.sleep(fixedDelay + rnd.nextLong() % randMod);

} }

protected abstract moveStuff(final Object source, final Object target);

}

Thursday, April 28, 2011

(14)

Fairness of locks

“When set true, under contention, locks favor granting access to the longest-waiting

thread. Otherwise this lock does not guarantee any particular access order. “

(15)

Always Mutual Exclusion ?

15 public class ReadWriteMap<K,V> { private final Map<K,V> map;

private final ReadWriteLock lock = new ReentrantReadWriteLock();

private final Lock r = lock.readLock();

private final Lock w = lock.writeLock();

public ReadWriteMap(Map<K,V> map) { this.map = map;

}

public V put(K key, V value) { w.lock();

try {

return map.put(key, value);

} finally {

w.unlock();

} }

// Do the same for remove(), putAll(), clear() public V get(Object key) {

r.lock();

try {

return map.get(key);

} finally {

r.unlock();

} }

// Do the same for other read-only Map methods }

Thursday, April 28, 2011

(16)

Results

(17)

Multithreaded on JVM Level

17

public class PossibleReordering { static int x = 0, y = 0;

static int a = 0, b = 0;

public static void main(String[] args) throws InterruptedException {

Thread one = new Thread(new Runnable() { public void run() {

a = 1;

x = b;

} });

Thread other = new Thread(new Runnable() { public void run() {

b = 1;

y = a;

} });

one.start(); other.start();

one.join(); other.join();

System.out.println("( "+ x + "," + y + ")");

} }

Boils down to the “happens-before” rule.

Thursday, April 28, 2011

(18)

Reordering

(19)

Effects to publication

19

@NotThreadSafe

public class Resource {

private static Resource resource;

private Resource(){

}

public static Resource getInstance() { if (resource == null)

resource = new Resource(); // unsafe publication return resource;

} }

Thursday, April 28, 2011

(20)

Safer

@ThreadSafe

public class SafeLazyInitialization { private static Resource resource;

public synchronized static Resource getInstance() { if (resource == null)

resource = new Resource();

return resource;

} }

@ThreadSafe

public class EagerInitialization {

private static Resource resource = new Resource();

public static Resource getResource() { return resource; } }

(21)

Double Checked Locking

21

public class DoubleCheckedLocking { private static Resource resource;

public static Resource getInstance() { if (resource == null) {

synchronized (DoubleCheckedLocking.class) { if (resource == null)

resource = new Resource();

} }

return resource;

} }

Thursday, April 28, 2011

(22)

Holder Class & Enums

@ThreadSafe

public class ResourceFactory {

private static class ResourceHolder {

public static Resource resource = new Resource();

}

public static Resource getResource() { return ResourceHolder.resource ; }

}

@ThreadSafe

public enum EnumInitialization { SINGLETON;

final Resource resource = new Resource();

}

(23)

Discussion + Feedback

‣ What was repetition?

‣ What will you use in the future?

‣ What is missing, what can be simplified?

23

Thursday, April 28, 2011

(24)

Next…Design Patterns

Any further questions

(or other information about projects in our working group)

sebastian.graf@uni-konstanz.de

Referenzen

ÄHNLICHE DOKUMENTE

The large-scale variations between countries, together with the similarity observed among apple microbial com- munities within a country or region within a country, sug- gests that

They expressed sentiments of trust in their children’s teachers and schools, and they were eager to be shared partners who supported their children’s technology use for

The file exercise3.zip contains a few interfaces and classes that constitute a simple client server application. Your task is to integrate the different creational patterns into

FractionBase : Abstract class that provides an implementation of one of the methods defined in Fraction, as well as the utility method greatestCommonFactor that subclasses

• the type of an expression as a result of the types of all involved literals; use the usual implicit type cast rules to infer the type of an operation whose two operands don’t have

The course home page also has a link to an RSS Feed for short-term announcements. Please subscribe to stay

Managing access to state, in particular to shared, mutable state (directly to member- variables of one class) with. ‣ Atomic change

‣ Guarded: Access to the object only possible when given lock held including encluding other thread-safe objects..