1 / 80

Concurrency in Java

Concurrency in Java. (Shooting yourself in the foot) n. Acknowledgment. This lecture is derived almost exclusively from Java Concurrency in Practice by Goetz, et. al. http://www.javaconcurrencyinpractice.com Additional notes from Dr. Dan Wallach. Outline. Background

tovi
Download Presentation

Concurrency in Java

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Concurrency in Java (Shooting yourself in the foot)n

  2. Acknowledgment • This lecture is derived almost exclusively from Java Concurrency in Practice by Goetz, et. al. http://www.javaconcurrencyinpractice.com • Additional notes from Dr. Dan Wallach

  3. Outline • Background • Basic Thread Safety • Concurrent Object Management • Concurrent Library Components • Task Execution and Shutdown

  4. Next Time • Thread Pools • GUI Applications • Safety and Performance • Documentation and Testing • Adv. Topics • Explicit Locks • Custom Synchronizers • Nonblocking Synchronization

  5. Background • Why concurrency? • Resource utilization - why wait? • Fairness - why wait? • Convenience - why wait? • First concurrency: processes • Later: threads

  6. Benefits of Threads • Responsiveness (esp. GUIs) • Exploiting multi-processors • Simplicity of modeling • Simplified handling of asynchronous events

  7. Risks of Threads • Java’s “built-in” threads means that concurrency is NOT an advanced topic • Safety hazards (correctness) • Liveness hazards (progress) • Performance hazards (happiness)

  8. Threads are Everywhere • Frameworks use threads • Timer • Servlets and JSPs • RMI • Swing and AWT • You will use this one!

  9. Starting a Java Thread public class HelloRunnable implements Runnable { public void run() { System.out.println("Hello from a thread!"); } public static void main(String args[]) { (new Thread(new HelloRunnable())).start(); } } public class HelloThread extends Thread { public void run() { System.out.println("Hello from a thread!"); } public static void main(String args[]) { (new HelloThread()).start(); } }

  10. Outline • Background • Basic Thread Safety • Concurrent Object Management • Concurrent Library Components • Task Execution and Shutdown

  11. Synchronization • Given a mutable variable v • If multiple threads access v • AND if one can modify v • ALL must synchronize access • This includes read access • Never attempt to ignore this • If sync is broken, so is the code (even if it passes tests)

  12. Concurrent Correctness • Fixing a broken “shared” var • Don’t Share!Or • Make the var immutable!Or • Synchronize access • Better yet, design it right • Encapsulation • Immutability • Clear specifications of invariants

  13. What is “Thread-Safe”? • Definitions are vague and vary • Problem: what is correctness? • Thread Safe: • “Correct” in multi-threaded env • OR, no more broken in a mult-threaded environment then in a single-threaded one • Thread-safe classes encapsulate all synchronization

  14. Example: Unsafe Counter @NoThreadSafe public class UnsafeSequence{ private int value; public int getNext() { return value++; } }

  15. What’s Wrong with That? • Invariant: • getNext must return a sequence • Unlucky execution timing: Value->9 9+1->10 Value=10 Value->9 9+1->10 Value=10

  16. Race Conditions • The problem is a race condition • Def: r.c. occurs when the correctness of a computation depends on the relative timing of multiple threads by the runtime. • Often confused for data race

  17. Achieving Safety • Go stateless! • Use atomic operations • Use locking

  18. Using Atomics!(It’s not a treaty violation) @ThreadSafe public class UnsafeSequence{ private final AtomicLong value = new AtomicLong(0); public long getNext() { return value.incrementAndGet(); } }

  19. Locking • Solved one mutable variable by making the var atomic • What if we have 2? Can we just make them both atomic? • NOT if they are dependent • We have to lock any combined operations

  20. Example • Suppose we have a dictionary that stores the last (key,value) pair • Setting the (k,v) pair must be locked. It is not enough to use an atomic var for k, and another one for v

  21. Intrinsic Locks • Java provides built-in locks • Each object is a lock, so is each class • Marked by synchronized • Enforces • Atomicity • Memory visibility (more later)

  22. Reentrancy • Requesting a lock held by another causes a block • Intrinsic locks are reentrant • A thread that owns a lock, that requests the same lock, will succeed (good for inheritance!)

  23. Example Locking @ThreadSafe Public class LockSafe<K,V> { @GuardedBy(“this”) private K key; @GuardedBy(“this”) private V value; public synchronized setKvPair(K k, V v) { this.key = k; this.value = v; } }

  24. Locks: “Guarded By” “For each mutable state variable that may be accessed by more than one thread, all accesses to that variable must be performed with the same lock held. In this case, we say that the variable is guarded by that lock” (JCP 28)

  25. Locks: Documentation “Every shared, mutable variable should be guarded by exactly one lock. Make it clear to maintainers which lock that is” - (JCP p28)

  26. Locks: Across Invariants “For every invariant that involves more that one variable, all the variables involved in that invariant must be guarded by the same lock” - (JCP p29)

  27. Critical Concept • Any mutable state that can be concurrently accessed, must be synchronized EVERYWHERE else in the program! • EXAMPLE: TimerTask (JCP p29)

  28. Why Not Lock Everything? • Even if every method were synchronized, it doesn’t solve actions that combine those methods! (example: vector) • Also, possible liveness and/or performance problems • Poor concurrency example (JCP p30)

  29. Lock Advice “Avoid holding locks during lengthy computations or operations at risk of not completing quickly such as network or console I/O” - (JCP p32)

  30. More Syntax • Other use of synchronized public somemethod() { synchronized(this) { // do stuff } }

  31. Outline • Background • Basic Thread Safety • Concurrent Object Management • Concurrent Library Components • Task Execution and Shutdown

  32. Sharing Objects • Memory Visibility • Shared object modification should be visible to other threads • Without synchronization, this may not happen

  33. More about Visibility “In general, there is no guarantee that the reading thread will see a value written by another thread on a timely basis, or even at all” - (JCP p33)

  34. Public class NoVisibility { private static boolean ready; private static int number; private static class ReaderThread extends Thread { public void run() { while (!ready) Thread.yield() System.out.println(number) } } public static void main(String[] args) { new ReaderThread().start(); number = 42; ready = true; } }

  35. NoVisibility :( • NoVisibility could loop forever! • NoVisibility could write 0 through reordering • Other badness and sadness • Don’t do this!

  36. Synchronization Helps • NoVisibility demonstrates stale data • Synchronization must be used on all shared variables, even just for reads • Enforces memory visibility

  37. A Word about 64bit • When a thread reads a var w/o synchronization, at worst it is stale, but not random • Out-of-thin-air safety • One exception: 64 bit numbers (double and long) • Read/write can be 2 32 bit operations!

  38. Volatile Variables • Can declare a java var volatile • Volatile ensures visibility, but not locking. • Volatile use can be fragile. Many times, you shouldn’t use it • Good uses of volatile • Ensure visibility of their own state • That of the object they refer to • Or indicate that an important event has occurred (e.g. shutdown)

  39. Use Volatile ONLY when • Writes to the var do not depend on its current value or are only written by one thread • The var does not participate with invariants with other state vars • Locking is not required for any other reason when the var is being accessed

  40. Publication and Escape • Publishing an object - makes it available outside current scope • Many times, objects should not be published at all • Breaks encapsulation • Not fully constructed (!) • Object published when it should not have been is said to have escaped!

  41. Publication Methods • Public static fields • Chained publication • Special Case: published inner class • Passing to an alien method

  42. How Escape Happens • All linked to poor design • Semantic escapes: • Return ref instead of copy • Inadvertent chained publication • Syntactic escapes: • Escaped this during construction • “Object not properly constructed”

  43. This Escape Example Public class ThisEscape { // JCP p41 public ThisEscape(Eventsource source) { source.registerListener( new EventListener() { public void onEvent(Event e) { doSomething(e); } }); } }

  44. Preventing Escape • Thread Confinement • Immutability • Safe Publication

  45. Thread Confinement • Keep mutable vars confined to a single thread • Ad-hoc = enforced by impl. • Stack Confinement • Local vars • Violated by publication • ThreadLocal • Per thread value holding object

  46. Immutable Objects • Always thread safe • Can’t escape after construction • Definition • It’s state cannot be modified after construction • All fields are final* • Properly constructed • Can have mutable variables

  47. Final Fields • Can’t be modified • AND, have special semantics in the Java Memory model (initialization safety) • Make all fields final by default • “Mostly Immutable” is better than mutable

  48. Using Volatile Again! • Volatile can be used to publish immutable objects • Still not locked, but can be safe depending on semantics • Example - JCP p49-50

  49. Improper Publication • If synchronization is not used to publish a mutable object, the object is not properly published • Without proper publication, there are serious problems with stale data

  50. Safe Publication • Object reference and object state must become visible at the same time! • Idioms: • Initializing from static initializer • Storing ref in volatile or AtomicReference • Storing ref in final field of properly constructed object • Storing ref in a lock-guarded field

More Related