Understanding Java Thread Synchronization: Challenges and Best Practices - Prof. William P, Quizzes of Programming Languages

This document, written by doug lea and william pugh, discusses the complexities of java thread synchronization as outlined in the java language and virtual machine specifications. It covers safety issues in multithreaded systems, the need for revising the thread specification, and guidelines for efficient and reliable synchronization. The document also includes examples and quizzes to help readers understand the concepts.

Typology: Quizzes

Pre 2010

Uploaded on 07/30/2009

koofers-user-ouw
koofers-user-ouw 🇺🇸

9 documents

1 / 9

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
Correct and Efficient Synchronization of Java Threads 6/8/00
TS-754, William Pugh and Doug Lea 1
TS-754, Correct and Efficient Synchronization of Java Threads1
Correct and Efficient
Synchronization of
Java Technology-
based Threads
Doug Lea and William Pugh
http://gee.cs.oswego.edu
http://www.cs.umd.edu/~pugh
TS-754, Correct and Efficient Synchronization of Java Threads2
Audience
Assume you are familiar with basics
of Java technology-based threads
(“Java threads”)
Creating, starting and joining threads
Synchronization
wait and notifyAll
Will talk about things that surprised a lot
of experts
Including us, James Gosling, Guy Steele, …
(others discovered many of these)
TS-754, Correct and Efficient Synchronization of Java Threads3
Java Thread Specification
Chapter 17 of the Java Language Spec
Chapter 8 of the Virtual Machine Spec
Very, very hard to understand
Not even the authors understood it
Has subtle implications
That forbid standard compiler optimizations
All existing JVMs violate the specification
Some parts should be violated
TS-754, Correct and Efficient Synchronization of Java Threads4
Safety Issues in
Multithreaded Systems
Many intuitive assumptions do not hold
Some widely used idioms are not safe
Double-check idiom
Checking non-volatile flag for
thread termination
Can’t use testing to check for errors
Some anomalies will occur only on
some platforms
e.g., multiprocessors
TS-754, Correct and Efficient Synchronization of Java Threads5
Revising the Thread Spec
Work is underway to consider revising the
Java Thread Spec
http://www.cs.umd.edu/~pugh/java/memoryModel
Goals
Clear and easy to understand
Foster reliable multithreaded code
Allow for high performance JVMs
Will effect JVMs
And badly written existing code
Including parts of Sun’s JDK
TS-754, Correct and Efficient Synchronization of Java Threads6
What to do Today?
Guidelines we will provide should
work under both existing and future
thread specs
Don’t try to read the official specs
Avoid corner cases of the thread spec
Not needed for efficient and reliable programs
pf3
pf4
pf5
pf8
pf9

Partial preview of the text

Download Understanding Java Thread Synchronization: Challenges and Best Practices - Prof. William P and more Quizzes Programming Languages in PDF only on Docsity!

1 TS-754, Correct and Efficient Synchronization of Java Threads

Correct and Efficient

Synchronization of

Java™^ Technology-

based Threads

Doug Lea and William Pugh

http://gee.cs.oswego.edu

http://www.cs.umd.edu/~pugh

2 TS-754, Correct and Efficient Synchronization of Java Threads

Audience

  • Assume you are familiar with basics

of Java™^ technology-based threads

(“Java threads”)

  • Creating, starting and joining threads
  • Synchronization
  • wait and notifyAll
  • Will talk about things that surprised a lot

of experts

  • Including us, James Gosling, Guy Steele, … (others discovered many of these)

3 TS-754, Correct and Efficient Synchronization of Java Threads

Java Thread Specification

  • Chapter 17 of the Java Language Spec
    • Chapter 8 of the Virtual Machine Spec
  • Very, very hard to understand
    • Not even the authors understood it
    • Has subtle implications
      • That forbid standard compiler optimizations
    • All existing JVMs violate the specification
      • Some parts should be violated

4 TS-754, Correct and Efficient Synchronization of Java Threads

Safety Issues in

Multithreaded Systems

  • Many intuitive assumptions do not hold
  • Some widely used idioms are not safe
    • Double-check idiom
    • Checking non-volatile flag for thread termination
  • Can’t use testing to check for errors
    • Some anomalies will occur only on some platforms - e.g., multiprocessors

5 TS-754, Correct and Efficient Synchronization of Java Threads

Revising the Thread Spec

  • Work is underway to consider revising the

Java Thread Spec

  • http://www.cs.umd.edu/~pugh/java/memoryModel
  • Goals
  • Clear and easy to understand
  • Foster reliable multithreaded code
  • Allow for high performance JVMs
  • Will effect JVMs
  • And badly written existing code
  • Including parts of Sun’s JDK 6 TS-754, Correct and Efficient Synchronization of Java Threads

What to do Today?

  • Guidelines we will provide should

work under both existing and future

thread specs

  • Don’t try to read the official specs
  • Avoid corner cases of the thread spec
    • Not needed for efficient and reliable programs

7 TS-754, Correct and Efficient Synchronization of Java Threads

Three Aspects of

Synchronization

  • Atomicity
    • Locking to obtain mutual exclusion
  • Visibility
    • Ensuring that changes to object fields made in one thread are seen in other threads
  • Ordering
    • Ensuring that you aren’t surprised by the order in which statements are executed

8 TS-754, Correct and Efficient Synchronization of Java Threads

Don’t Be Too Clever

  • People worry about the cost of

synchronization

  • Try to devise schemes to communicate between threads - Without using synchronization
  • Very difficult to do correctly
  • Inter-thread communication without synchronization is not intuitive

9 TS-754, Correct and Efficient Synchronization of Java Threads

Quiz Time

x = y = 0

x = 1

j = y

Thread 1 y = 1

i = x

Thread 2

Can this result in i = 0 and j = 0?

start threads

10 TS-754, Correct and Efficient Synchronization of Java Threads

Answer: Yes!

x = y = 0

x = 1

j = y

Thread 1 y = 1

i = x

Thread 2

How can i = 0 and j = 0?

start threads

11 TS-754, Correct and Efficient Synchronization of Java Threads

How Can This Happen?

  • Compiler can reorder statements
    • Or keep values in registers
  • Processor can reorder them
  • On multi-processor, values not

synchronized in global memory

  • Must use synchronization to enforce

visibility and ordering

  • As well as mutual exclusion

12 TS-754, Correct and Efficient Synchronization of Java Threads

Synchronization Actions

( approximately )

// block until obtain lock synchronized(anObject) { // get main memory value of field1 and field int x = anObject.field1; int y = anObject.field2; anObject.field3 = x+y; // commit value of field3 to main memory } // release lock moreCode();

19 TS-754, Correct and Efficient Synchronization of Java Threads

Why Use Volatile?

  • Since the semantics are implemented

inconsistently

  • Future-proof your code
    • Prohibit optimizations compilers might do in the future
  • Works well for flags
    • More complicated uses are tricky
  • Revising the thread spec...
    • Test compliance
    • Strengthen to make easier to use 20 TS-754, Correct and Efficient Synchronization of Java Threads

Cost of Synchronization

  • Few good public multithreaded

benchmarks

  • See us if you want to help
  • Volano Benchmark
  • Most widely used server benchmark
  • Multithreaded chat room server
  • Client performs 4.8M synchronizations
  • 8K useful (0.2%)
  • Server 43M synchronizations
  • 1.7M useful (4%)

21 TS-754, Correct and Efficient Synchronization of Java Threads

Synchronization in

VolanoMark Client

90.3%

5.6% 1.8% 0.9% 0.9% 0.4% 0.2%

java.io.BufferedInputStream java.io.BufferedOutputStream java.util.Observable java.util.Vector java.ioeveryth.FinilterIng elseputStream All shared monitors

7,684 synchronizations on shared monitors 4,828,130 thread local synchronizations

22 TS-754, Correct and Efficient Synchronization of Java Threads

Cost of Synchronization

in VolanoMark

  • Removed synchronization of
    • java.io.BufferedInputStream
    • java.io.BufferedOutputStream
  • Performance (2 processor Ultra 60)
    • Larger is better
    • HotSpot (1.3 beta)
      • Original: 4788
      • Altered: 4923 (+3%)
    • Exact VM (1.2.2)
      • Original: 6649
      • Altered: 6874 (+3%)

23 TS-754, Correct and Efficient Synchronization of Java Threads

Most Synchronization is on

Thread Local Objects

  • Synchronization on thread local object
    • Is useless
    • Current spec says it isn’t quite a no-op
      • But very hard to use usefully
    • Revised spec will likely make it a no-op
  • Largely arises from using synchronized

classes

  • In places where not required

24 TS-754, Correct and Efficient Synchronization of Java Threads

Synchronize when Needed

  • Places where threads interact
    • Need synchronization
    • Need careful thought
    • Need documentation
    • Cost of required synchronization not significant
      • For most applications
      • No need to get tricky
  • Elsewhere, using a synchronized class can

be expensive

25 TS-754, Correct and Efficient Synchronization of Java Threads

Synchronized Classes

  • Some classes are synchronized
    • Vector, Hashtable, Stack
    • Most Input/Output Streams
  • Contrast with 1.2 Collection classes
    • By default, not synchronized
    • Can request synchronized version
  • Using synchronized classes
    • Often doesn’t suffice for concurrent interaction

26 TS-754, Correct and Efficient Synchronization of Java Threads

Synchronized Collections

Aren’t Always Enough

  • Transactions (DO NOT USE)

ID getID(String name) {

ID x = (ID) h.get(name);

if (x == null) {

x = new ID();

h.put(name, x);}

return x; }

  • Iterators
    • Can’t modify collection while another thread is iterating through it

27 TS-754, Correct and Efficient Synchronization of Java Threads

Concurrent Interactions

  • Often need entire transactions to

be atomic

  • Reading and updating a Map
  • Writing a record to an OutputStream
  • OutputStreams are synchronized
  • Can have multiple threads trying to write to the same OutputStream
  • Output from each thread is nondeterministicly interleaved
  • Essentially useless

28 TS-754, Correct and Efficient Synchronization of Java Threads

Cost of Synchronization in

SpecJVM DB Benchmark

  • Program in the Spec JVM benchmark
  • Does lots of synchronization
    • 53,000,000 syncs - 99.9% comes from use of Vector - Benchmark is single threaded, all of it is useless

  • Tried
    • Remove synchronizations
    • Switching to ArrayList
    • Improving the algorithm

29 TS-754, Correct and Efficient Synchronization of Java Threads

Execution Time of Spec JVM

_209_db, Hotspot Server

0

10

20

30

40

Original 35.5 32.6 28.5 16.2 12. Without Syncs 30.3^ 32.5^ 28.5^ 14.0^ 12.

Original (^) ArrayListUse ArrayListUse and otherminor Shell SortChange to MergeSort All

30 TS-754, Correct and Efficient Synchronization of Java Threads

Lessons

  • Synchronization cost can be substantial
    • 10-20% for DB benchmark
    • Consider replacing all uses of Vector, Hashtable and Stack
  • Use profiling
  • Use better algorithms!
    • Cost of stupidity higher than cost of synchronization
    • Used built-in merge sort rather than hand-coded shell sort

37 TS-754, Correct and Efficient Synchronization of Java Threads

Initialization checks - v2 - OK

Isolate check: class ServiceV2 { Parser parser = null; synchronized Parser getParser() { if (parser == null) parser = new Parser(); return parser; } public void command(...) { doCommand(getParser().parse(...)); }} 38 TS-754, Correct and Efficient Synchronization of Java Threads

Single-check - DO NOT USE

Try to do it without synchronization: class ServiceV3 { // DO NOT USE Parser parser = null; Parser getParser() { if (parser == null) parser = new Parser(); return parser; }}

39 TS-754, Correct and Efficient Synchronization of Java Threads

Double-check - DO NOT USE

Try to minimize likelihood of synch: class ServiceV4 { // DO NOT USE Parser parser = null; Parser getParser() { if (parser == null) synchronized(this) { if (parser == null) parser = new Parser(); } return parser; }} 40 TS-754, Correct and Efficient Synchronization of Java Threads

Problems with Double-check

  • Can reorder
    • Initialization of Parser object
    • Store into parser field
  • …Among other reasons
    • See JMM web page for gory details
  • Can go wrong on uniprocessors
    • e.g., Symantic JIT
  • Using volatile doesn’t help
    • Under current JMM

41 TS-754, Correct and Efficient Synchronization of Java Threads

Alternatives to

Double–Check

  • Use synchronization
  • Double check OK for primitive values
    • hashCode caching (still technically a data race)
  • For static singletons
    • Put in separate class
    • First use of a class forces class initialization
    • Later uses guaranteed to see class initialization
    • No explicit check needed

42 TS-754, Correct and Efficient Synchronization of Java Threads

Rare Heavy New Objects

  • Sometimes, need singleton that is

expensive to create

static final Font HELVETICA = new FONT(“Helvetica”,Font.PLAIN, 24);

Font getFont() { if (!chinese) return HELVETICA; else return new ChineseFont(); }

43 TS-754, Correct and Efficient Synchronization of Java Threads

Using Static Singletons

static final Font HELVETICA = new Font(“Helvetica”,Font.PLAIN,24);

static class CFSingleton{ static final Font CHINESE = new ChineseFont(...); } Font getFont() { if (!chinese) return HELVETICA; else return CFSingleton.CHINESE; }

44 TS-754, Correct and Efficient Synchronization of Java Threads

Unsynchronized

Reads/Writes of References

  • Beware of unsynchronized getX/setX

methods that return a reference

  • Same problems as double check
  • Doesn’t help to synchronize only setX private Color color; void setColor(int rgb) { color = new Color(rgb); } Color getColor() { return color; }

45 TS-754, Correct and Efficient Synchronization of Java Threads

Thread blinker = null; public void start() { blinker = new Thread(this); blinker.start(); } public void stop() { blinker = null;} public void run() { Thread me = Thread.currentThread(); while (blinker == me) { try {Thread.currentThread().sleep(delay);} catch (InterruptedException e) {} repaint(); } }

Thread Termination in

Sun’s Demo Applets

unsynchronized access to blinker field

confusing but not wrong: sleep is a static method 46 TS-754, Correct and Efficient Synchronization of Java Threads

Problems

  • Don’t assume another thread will see

your writes

  • Just because you did them
  • Calling sleep doesn’t guarantee you see

changes made while you slept

  • Nothing to force thread that called stop to push change out of registers/cache

47 TS-754, Correct and Efficient Synchronization of Java Threads

Wrap-up

  • Cost of synchronization operations

can be significant

  • But cost of needed synchronization rarely is
  • Thread interaction needs careful thought
  • But not too clever
  • Need for synchronization...

48 TS-754, Correct and Efficient Synchronization of Java Threads

Wrapup - Synchronization

  • Communication between threads
    • Requires both threads to synchronize
      • Or communication through volatile fields
  • Synchronizing everything
    • Is rarely necessary
    • Can be expensive (3%-20% overhead)
    • May lead to deadlock
    • May not provide enough synchronization
      • e.g., transactions