SlideShare a Scribd company logo
1 of 54
Download to read offline
Java™ Platform
Concurrency Gotchas


Alex Miller
Terracotta
Questions to answer

>   What are common concurrency problems?
>   Why are they problems?
>   How do I detect these problems?
>   How do I correct these problems?




                                            2
Taxonomy of Concurrency Gotchas

>   Shared Data
>   Coordination
>   Performance




                                  3
Shared Data

>   Locking
>   Visibility
>   Atomicity
>   Safe Publication




                       4
What happens if we modify
  data without locking?




                            5
What happens if we modify
  data without locking?



                   Hint: itʼs not good.




                                          5
6
Mutable Statics
public class MutableStatics {
                                             FORMAT is mutable
    private static final DateFormat FORMAT =
     DateFormat.getDateInstance(DateFormat.MEDIUM);

    public static Date parse(String str)
    throws ParseException {
                                ...and this mutates it
      return FORMAT.parse(str);
                                outside synchronization
    }

    public static void main(String arg[]) {
      MutableStatics.parse(“Jan 1, 2000”);
    }
}

                                                                 7
Mutable Statics - instance per call
public class MutableStatics {

    public static Date parse(String str)
    throws ParseException {
      DateFormat format =
        DateFormat.getDateInstance(DateFormat.MEDIUM);
      return format.parse(str);
    }

    public static void main(String arg[]) {
      MutableStatics.parse(“Jan 1, 2000”);
    }
}


                                                         8
Synchronization
private int myField;


synchronized( What goes here? ) {
    myField = 0;
}




                                    9
DO NOT synchronize on null
MyObject obj = null;


synchronized( obj ) {   NullPointerException!
    // stuff
}




                                                10
DO NOT change instance
MyObject obj = new MyObject();


synchronized( obj ) {
                            No longer synchronizing
    obj = new MyObject();    on the same object!
}




                                                      11
12
DO NOT synchronize on string literals
private static final String LOCK = “LOCK”;
synchronized( LOCK ) {
                            What is the scope
    // work                    of LOCK?
}




                                                13
DO NOT synchronize on autoboxed instances
private static final Integer LOCK = 0;
synchronized( LOCK ) {
                          What is the scope
    // work                  of LOCK?
}




                                              14
DO NOT synchronize on ReentrantLock
final Lock lock = new ReentrantLock();
synchronized( lock ) {     Probably not what
  // work                   you meant here
}


final Lock lock = new ReentrantLock();
lock.lock();
                               Probably should
try {                           be this instead
  // ...
} finally {
  lock.unlock();
}



                                                  15
What should I lock on?
// The field you are protecting
private final Map map = ...
synchronized(map) {
  // ...access map
}




// Or an explicit lock object
private final Object lock = new Object();
synchronized(lock) {
  // ... modify state
}



                                            16
Visibility




             17
Inconsistent Synchronization
public class SomeData {
  private final Map data = new HashMap();

    public void put(String key, String value) {
      synchronized(data) {
        data.put(key, value);   Modified under synchronization
      }
    }

    public String get(String key) {
      return data.get(key);     Read without synchronization
    }
}



                                                                18
Double-checked locking
public final class Singleton {
  private static Singleton instance;

    public static Singleton getInstance() {
      if(instance == null) {            Attempt to avoid synchronization
        synchronized(Singleton.class) {
          if(instance == null) {
            instance = new Singleton();
          }
        }
      }
      return instance;
    }
}


                                                                           19
Double-checked locking
public final class Singleton {
  private static Singleton instance;

    public static Singleton getInstance() {
      if(instance == null) {              READ
        synchronized(Singleton.class) {
          if(instance == null) {            READ
            instance = new Singleton();     WRITE
          }
        }
      }
      return instance;
    }
}


                                                    19
Double-checked locking - volatile
public class Singleton {
  private static volatile Singleton instance;

  public static Singleton getInstance() {
    if(instance == null) {
      synchronized(Singleton.class) {
        if(instance == null) {
          instance = new Singleton();
        }
      }
    }
    return INSTANCE;
  }



                                                20
Double-checked locking - initialize on demand
public class Singleton {

    private static class SingletonHolder {
      private static final Singleton instance = new Singleton();
    }

    public static Singleton getInstance() {
      return SingletonHolder.instance;
    }
}




                                                               21
Racy single-check
public final class String {
  private int hash;              // default to 0
  private final char[] value;    // immutable

    public int hashCode() {
      int h = hash;
      if(h == 0) {
        // ... compute value for h from data
        hash = h;
      }
      return h;
    }
}



                                                   22
volatile arrays
public final class VolatileArray {
  private volatile boolean[] vals;

    public void flip(int i) {
      vals[i] = true;       Is the value of vals[i]
    }                       visible to other threads?

    public boolean flipped(int i) {
      return vals[i];
    }
}




                                                        23
Atomicity




            24
Volatile counter
public class Counter {
    private volatile int count;


    public int next() {
        return count++;   Looks atomic to me!
    }
}




                                                25
AtomicInteger counter

public class Counter {
    private final AtomicInteger count = new AtomicInteger();


    public int next() {
                                          Really atomic by
        return count.getAndIncrement();   encapsulating
    }                                     multiple actions

}




                                                               26
Composing atomic actions
public Object putIfAbsent(
   Hashtable table, Object key, Object value) {
        Hashtable is thread-safe
    if(table.containsKey(key)) {                      READ
      // already present, return existing value
      return table.get(key);                          READ
    } else {
      // doesn’t exist, create and return new value
      table.put(key, value);                          WRITE
      return value;
    }
}




                                                              27
Composing atomic actions
public Object putIfAbsent(
   Hashtable table, Object key, Object value) {
        Hashtable is thread-safe
    if(table.containsKey(key)) {                      READ
      // already present, return existing value
      return table.get(key);                          READ
    } else {
      // doesn’t exist, create and return new value
      table.put(key, value);                          WRITE
      return value;
    }
}




                                                              27
Participate in lock
public Object putIfAbsent(
   Hashtable table, Object key, Object value) {

    synchronized(table) {        Protect with synchronization
      if(table.containsKey(key)) {
        return table.get(key);
      } else {
        table.put(key, value);
        return value;
      }
    }
}




                                                                28
Encapsulated compound actions

public Object putIfAbsent(
    ConcurrentHashMap table, Object key, Object value) {


    table.putIfAbsent(key, value);
}




                                                           29
Assignment of 64 bit values
public class LongAssignment {
    private long x;


    public void setLong(long val) {
        x = val;   Looks atomic to me -
    }              but is it?
}




                                          30
Assignment of 64 bit values - volatile
public class LongAssignment {
    private volatile long x;


    public void setLong(long val) {
        x = val;
    }
}




                                         31
Safe publication




                   Intentionally left blank.




                                               32
Listener in constructor
public interface DispatchListener {
  void newFare(Customer customer);
}

public class Taxi implements DispatchListener {
  public Taxi(Dispatcher dispatcher) {
    dispatcher.registerListener(this);
                                       We just published a
    // other initialization            reference to this - oops!
  }

    public void newFare(Customer customer) {
      // go to new customer's location
    }
}


                                                                   33
Starting thread in constructor
public class Cache {
  private final Thread cleanerThread;

    public Cache() {                       this escapes again!
      cleanerThread = new Thread(new Cleaner(this));
      cleanerThread.start();
    }

    // Cleaner calls back to this method
    public void cleanup() {
      // clean up Cache
    }
}



                                                                 34
Static factory method
public class Cache {
    // ...


    public static Cache newCache() {
        Cache cache = new Cache();
        cache.startCleanerThread();
        return cache;
    }
}




                                       35
Coordination

>   Threads
>   wait/notify




                  36
Threads

>   DO NOT:
    • Call Thread.stop()
    • Call Thread.suspend() or Thread.resume()
    • Call Thread.destroy()
    • Call Thread.run()
    • Use ThreadGroups



                                                 37
wait/notify
// Thread 1
synchronized(lock) {       You must synchronize.
    while(! someCondition()) {       Always wait in a loop.
        lock.wait();
    }
}


// Thread 2
synchronized(lock) { Synchronize here too.
    satisfyCondition();    Update condition!
    lock.notifyAll();
}


                                                              38
Performance

>   Deadlock
>   Spin wait
>   Lock contention




                      39
Deadlock
// Thread 1
synchronized(lock1) {
    synchronized(lock2) {   Classic deadlock.
        // stuff
    }
}


// Thread 2
synchronized(lock2) {
    synchronized(lock1) {
        // stuff
    }
}
                                                40
Deadlock avoidance

>   Lock splitting
>   Lock ordering
>   Lock timeout
>   tryLock




                     41
Spin wait
// Not efficient
private volatile boolean flag = false;


public void waitTillChange() {
    while(! flag) {
                             Spin on flag,
        Thread.sleep(100);   waiting for change
    }
}


public void change() {
    flag = true;
}


                                                  42
Replace with wait/notify
private final Object lock = new Object();
private boolean flag = false;

public void waitTillChange() {
  synchronized(lock) {
    while(! flag)      Wait/notify is far more
      lock.wait();     efficient than spin wait.
  }
}

public void change() {
  synchronized(lock) {
    flag = true;
    lock.notifyAll();
  }
}
                                                  43
Lock contention

                                     x




                                  Hash f(x)




            Bucket 0   Bucket 1           Bucket 2   Bucket 3




                                                                44
Lock striping
                                             x




                                          Hash g(x)




                       Hash f(x)                                 Hash f(x)




            Bucket 0           Bucket 1               Bucket 0           Bucket 1




                                                                                    45
Final Exam
public class StatisticsImpl implements Statistics,
StatisticsImplementor {
  private long queryExecutionCount;

  public synchronized void queryExecuted(String hql, int rows, long
time) {
    queryExecutionCount++;
    // ... other stat collection
  }

    public long getQueryExecutionCount() {
      return queryExecutionCount;
    }

    public synchronized void clear() {
      queryExecutionCount = 0;
      // ... clear all other stats
    }
}
                                                                      46
Final Exam
public class StatisticsImpl implements Statistics,
StatisticsImplementor {
  private long queryExecutionCount;

  public synchronized void queryExecuted(String hql, int rows, long
time) {
    queryExecutionCount++;
    // ... other stat collection
  }

    public long getQueryExecutionCount() {
      return queryExecutionCount;
                                  Read of shared value
    }
                                  without synchronization
    public synchronized void clear() {
      queryExecutionCount = 0;
      // ... clear all other stats
    }
}
                                                                      46
Final Exam
public class StatisticsImpl implements Statistics,
StatisticsImplementor {
  private long queryExecutionCount;

  public synchronized void queryExecuted(String hql, int rows, long
time) {
    queryExecutionCount++;
    // ... other stat collection
  }

    public long getQueryExecutionCount() {
      return queryExecutionCount;
                                  Read of shared value      Non-atomic read
    }
                                  without synchronization   of long value
    public synchronized void clear() {
      queryExecutionCount = 0;
      // ... clear all other stats
    }
}
                                                                              46
Final Exam
public class StatisticsImpl implements Statistics,
StatisticsImplementor {
  private long queryExecutionCount;

  public synchronized void queryExecuted(String hql, int rows, long
time) {
    queryExecutionCount++;
    // ... other stat collection
  }

    public long getQueryExecutionCount() {
      return queryExecutionCount;
                                  Read of shared value       Non-atomic read
    }
                                  without synchronization    of long value
    public synchronized void clear() {
      queryExecutionCount = 0;
                                       Race condition if reading stat and
      // ... clear all other stats     clearing - could be compound action
    }
}
                                                                               46
Final Exam
public class StatisticsImpl implements Statistics,
StatisticsImplementor {
  private long queryExecutionCount;

  public synchronized void queryExecuted(String hql, int rows, long
time) {
                             Single shared lock for ALL stat values
    queryExecutionCount++;
    // ... other stat collection
  }

    public long getQueryExecutionCount() {
      return queryExecutionCount;
                                  Read of shared value       Non-atomic read
    }
                                  without synchronization    of long value
    public synchronized void clear() {
      queryExecutionCount = 0;
                                       Race condition if reading stat and
      // ... clear all other stats     clearing - could be compound action
    }
}
                                                                               46
Alex Miller
Terracotta

Blog:    http://tech.puredanger.com
Twitter: @puredanger

More Related Content

What's hot

Qt Memory Management & Signal and Slots
Qt Memory Management & Signal and SlotsQt Memory Management & Signal and Slots
Qt Memory Management & Signal and SlotsJussi Pohjolainen
 
Java synchronizers
Java synchronizersJava synchronizers
Java synchronizersts_v_murthy
 
Qt Framework Events Signals Threads
Qt Framework Events Signals ThreadsQt Framework Events Signals Threads
Qt Framework Events Signals ThreadsNeera Mital
 
Groovy 1.8の新機能について
Groovy 1.8の新機能についてGroovy 1.8の新機能について
Groovy 1.8の新機能についてUehara Junji
 
Easy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVEEasy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVEUehara Junji
 
How Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzerHow Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzerAndrey Karpov
 
Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...
Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...
Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...Uehara Junji
 
Apache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheelApache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheeltcurdt
 
Arc of developer part1
Arc of developer part1Arc of developer part1
Arc of developer part1Junpei Wada
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesAndrey Karpov
 
Virtual Separation of Concerns
Virtual Separation of ConcernsVirtual Separation of Concerns
Virtual Separation of Concernschk49
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleThierry Wasylczenko
 

What's hot (19)

Qt Memory Management & Signal and Slots
Qt Memory Management & Signal and SlotsQt Memory Management & Signal and Slots
Qt Memory Management & Signal and Slots
 
Java synchronizers
Java synchronizersJava synchronizers
Java synchronizers
 
Qt Framework Events Signals Threads
Qt Framework Events Signals ThreadsQt Framework Events Signals Threads
Qt Framework Events Signals Threads
 
Groovy 1.8の新機能について
Groovy 1.8の新機能についてGroovy 1.8の新機能について
Groovy 1.8の新機能について
 
Easy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVEEasy Going Groovy 2nd season on DevLOVE
Easy Going Groovy 2nd season on DevLOVE
 
How Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzerHow Data Flow analysis works in a static code analyzer
How Data Flow analysis works in a static code analyzer
 
Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...
Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...
Let's go Developer 2011 sendai Let's go Java Developer (Programming Language ...
 
Apache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheelApache Commons - Don\'t re-invent the wheel
Apache Commons - Don\'t re-invent the wheel
 
Arc of developer part1
Arc of developer part1Arc of developer part1
Arc of developer part1
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
 
packet destruction in NS2
packet destruction in NS2packet destruction in NS2
packet destruction in NS2
 
Pre zen ta sion
Pre zen ta sionPre zen ta sion
Pre zen ta sion
 
Virtual Separation of Concerns
Virtual Separation of ConcernsVirtual Separation of Concerns
Virtual Separation of Concerns
 
NS2 Shadow Object Construction
NS2 Shadow Object ConstructionNS2 Shadow Object Construction
NS2 Shadow Object Construction
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 
Comparing JVM languages
Comparing JVM languagesComparing JVM languages
Comparing JVM languages
 
#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG
 
Sam wd programs
Sam wd programsSam wd programs
Sam wd programs
 
04 threads
04 threads04 threads
04 threads
 

Viewers also liked

Introduction to Configuration Management
Introduction to Configuration ManagementIntroduction to Configuration Management
Introduction to Configuration Managementripienaar
 
Nikki Giovanni
Nikki GiovanniNikki Giovanni
Nikki Giovanniextremeg35
 
SPM Meetup #35 Построение работы с дизайнерами подводные течения и медные трубы
SPM Meetup #35 Построение работы с дизайнерами подводные течения и медные трубыSPM Meetup #35 Построение работы с дизайнерами подводные течения и медные трубы
SPM Meetup #35 Построение работы с дизайнерами подводные течения и медные трубыLilia Gorbachik
 
Introduction to Docker
Introduction to DockerIntroduction to Docker
Introduction to Dockerripienaar
 
Whirlwind Tour of Puppet 4
Whirlwind Tour of Puppet 4Whirlwind Tour of Puppet 4
Whirlwind Tour of Puppet 4ripienaar
 
Kaust Admissions Look Book
Kaust Admissions Look BookKaust Admissions Look Book
Kaust Admissions Look Bookjoanna_oommen
 
Event-based MultiMedia Search and Retrieval for Question Answering
Event-based MultiMedia Search and Retrieval for Question AnsweringEvent-based MultiMedia Search and Retrieval for Question Answering
Event-based MultiMedia Search and Retrieval for Question AnsweringBenoit HUET
 
Monitoring using Sensu
Monitoring using SensuMonitoring using Sensu
Monitoring using Sensuripienaar
 
External Data in Puppet 4
External Data in Puppet 4External Data in Puppet 4
External Data in Puppet 4ripienaar
 
деньзнанийL для веб
деньзнанийL для  вебденьзнанийL для  веб
деньзнанийL для вебKaverzinatn
 
профсоюз
профсоюзпрофсоюз
профсоюзKaverzinatn
 

Viewers also liked (16)

Bp Tourney IV
Bp Tourney IVBp Tourney IV
Bp Tourney IV
 
Sérgio Leal Publications
Sérgio Leal PublicationsSérgio Leal Publications
Sérgio Leal Publications
 
Introduction to Configuration Management
Introduction to Configuration ManagementIntroduction to Configuration Management
Introduction to Configuration Management
 
CRJ
CRJCRJ
CRJ
 
Nikki Giovanni
Nikki GiovanniNikki Giovanni
Nikki Giovanni
 
SPM Meetup #35 Построение работы с дизайнерами подводные течения и медные трубы
SPM Meetup #35 Построение работы с дизайнерами подводные течения и медные трубыSPM Meetup #35 Построение работы с дизайнерами подводные течения и медные трубы
SPM Meetup #35 Построение работы с дизайнерами подводные течения и медные трубы
 
Olympia Gold Dp10
Olympia Gold Dp10Olympia Gold Dp10
Olympia Gold Dp10
 
Introduction to Docker
Introduction to DockerIntroduction to Docker
Introduction to Docker
 
Whirlwind Tour of Puppet 4
Whirlwind Tour of Puppet 4Whirlwind Tour of Puppet 4
Whirlwind Tour of Puppet 4
 
Kaust Admissions Look Book
Kaust Admissions Look BookKaust Admissions Look Book
Kaust Admissions Look Book
 
Event-based MultiMedia Search and Retrieval for Question Answering
Event-based MultiMedia Search and Retrieval for Question AnsweringEvent-based MultiMedia Search and Retrieval for Question Answering
Event-based MultiMedia Search and Retrieval for Question Answering
 
Monitoring using Sensu
Monitoring using SensuMonitoring using Sensu
Monitoring using Sensu
 
Nestle
NestleNestle
Nestle
 
External Data in Puppet 4
External Data in Puppet 4External Data in Puppet 4
External Data in Puppet 4
 
деньзнанийL для веб
деньзнанийL для  вебденьзнанийL для  веб
деньзнанийL для веб
 
профсоюз
профсоюзпрофсоюз
профсоюз
 

Similar to Javaoneconcurrencygotchas 090610192215 Phpapp02

第1回 チキチキ『( ゜ェ゜)・;'.、ゴフッ』 - シングルトンパターン(Java)
第1回 チキチキ『( ゜ェ゜)・;'.、ゴフッ』 - シングルトンパターン(Java)第1回 チキチキ『( ゜ェ゜)・;'.、ゴフッ』 - シングルトンパターン(Java)
第1回 チキチキ『( ゜ェ゜)・;'.、ゴフッ』 - シングルトンパターン(Java)潤一 加藤
 
Use of Apache Commons and Utilities
Use of Apache Commons and UtilitiesUse of Apache Commons and Utilities
Use of Apache Commons and UtilitiesPramod Kumar
 
3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в JavaDEVTYPE
 
20070329 Java Programing Tips
20070329 Java Programing Tips20070329 Java Programing Tips
20070329 Java Programing TipsShingo Furuyama
 
Effective java - concurrency
Effective java - concurrencyEffective java - concurrency
Effective java - concurrencyfeng lee
 
Java весна 2013 лекция 2
Java весна 2013 лекция 2Java весна 2013 лекция 2
Java весна 2013 лекция 2Technopark
 
K is for Kotlin
K is for KotlinK is for Kotlin
K is for KotlinTechMagic
 
OBJECTS IN Object Oriented Programming .ppt
OBJECTS IN Object Oriented Programming .pptOBJECTS IN Object Oriented Programming .ppt
OBJECTS IN Object Oriented Programming .pptSaadAsim11
 
Kotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime PerformanceKotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime Performanceintelliyole
 
Java осень 2012 лекция 2
Java осень 2012 лекция 2Java осень 2012 лекция 2
Java осень 2012 лекция 2Technopark
 
Concurrency Antipatterns In IDEA
Concurrency Antipatterns In IDEAConcurrency Antipatterns In IDEA
Concurrency Antipatterns In IDEAcdracm
 
Lecture 4: Data Types
Lecture 4: Data TypesLecture 4: Data Types
Lecture 4: Data TypesEelco Visser
 
A linked stack is implemented using a standard Node class as follows.pdf
A linked stack is implemented using a standard Node class as follows.pdfA linked stack is implemented using a standard Node class as follows.pdf
A linked stack is implemented using a standard Node class as follows.pdfkisgstin23
 

Similar to Javaoneconcurrencygotchas 090610192215 Phpapp02 (20)

第1回 チキチキ『( ゜ェ゜)・;'.、ゴフッ』 - シングルトンパターン(Java)
第1回 チキチキ『( ゜ェ゜)・;'.、ゴフッ』 - シングルトンパターン(Java)第1回 チキチキ『( ゜ェ゜)・;'.、ゴフッ』 - シングルトンパターン(Java)
第1回 チキチキ『( ゜ェ゜)・;'.、ゴフッ』 - シングルトンパターン(Java)
 
Concurrency gotchas
Concurrency gotchasConcurrency gotchas
Concurrency gotchas
 
Use of Apache Commons and Utilities
Use of Apache Commons and UtilitiesUse of Apache Commons and Utilities
Use of Apache Commons and Utilities
 
3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java
 
Scala in practice
Scala in practiceScala in practice
Scala in practice
 
20070329 Java Programing Tips
20070329 Java Programing Tips20070329 Java Programing Tips
20070329 Java Programing Tips
 
Effective java - concurrency
Effective java - concurrencyEffective java - concurrency
Effective java - concurrency
 
Java весна 2013 лекция 2
Java весна 2013 лекция 2Java весна 2013 лекция 2
Java весна 2013 лекция 2
 
K is for Kotlin
K is for KotlinK is for Kotlin
K is for Kotlin
 
Test Engine
Test EngineTest Engine
Test Engine
 
Mattbrenner
MattbrennerMattbrenner
Mattbrenner
 
OBJECTS IN Object Oriented Programming .ppt
OBJECTS IN Object Oriented Programming .pptOBJECTS IN Object Oriented Programming .ppt
OBJECTS IN Object Oriented Programming .ppt
 
Kotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime PerformanceKotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime Performance
 
Java осень 2012 лекция 2
Java осень 2012 лекция 2Java осень 2012 лекция 2
Java осень 2012 лекция 2
 
Concurrency Antipatterns In IDEA
Concurrency Antipatterns In IDEAConcurrency Antipatterns In IDEA
Concurrency Antipatterns In IDEA
 
Lecture 4: Data Types
Lecture 4: Data TypesLecture 4: Data Types
Lecture 4: Data Types
 
FSE 2008
FSE 2008FSE 2008
FSE 2008
 
Java concurrency
Java concurrencyJava concurrency
Java concurrency
 
Test Engine
Test EngineTest Engine
Test Engine
 
A linked stack is implemented using a standard Node class as follows.pdf
A linked stack is implemented using a standard Node class as follows.pdfA linked stack is implemented using a standard Node class as follows.pdf
A linked stack is implemented using a standard Node class as follows.pdf
 

Javaoneconcurrencygotchas 090610192215 Phpapp02

  • 2. Questions to answer > What are common concurrency problems? > Why are they problems? > How do I detect these problems? > How do I correct these problems? 2
  • 3. Taxonomy of Concurrency Gotchas > Shared Data > Coordination > Performance 3
  • 4. Shared Data > Locking > Visibility > Atomicity > Safe Publication 4
  • 5. What happens if we modify data without locking? 5
  • 6. What happens if we modify data without locking? Hint: itʼs not good. 5
  • 7. 6
  • 8. Mutable Statics public class MutableStatics { FORMAT is mutable private static final DateFormat FORMAT = DateFormat.getDateInstance(DateFormat.MEDIUM); public static Date parse(String str) throws ParseException { ...and this mutates it return FORMAT.parse(str); outside synchronization } public static void main(String arg[]) { MutableStatics.parse(“Jan 1, 2000”); } } 7
  • 9. Mutable Statics - instance per call public class MutableStatics { public static Date parse(String str) throws ParseException { DateFormat format = DateFormat.getDateInstance(DateFormat.MEDIUM); return format.parse(str); } public static void main(String arg[]) { MutableStatics.parse(“Jan 1, 2000”); } } 8
  • 10. Synchronization private int myField; synchronized( What goes here? ) { myField = 0; } 9
  • 11. DO NOT synchronize on null MyObject obj = null; synchronized( obj ) { NullPointerException! // stuff } 10
  • 12. DO NOT change instance MyObject obj = new MyObject(); synchronized( obj ) { No longer synchronizing obj = new MyObject(); on the same object! } 11
  • 13. 12
  • 14. DO NOT synchronize on string literals private static final String LOCK = “LOCK”; synchronized( LOCK ) { What is the scope // work of LOCK? } 13
  • 15. DO NOT synchronize on autoboxed instances private static final Integer LOCK = 0; synchronized( LOCK ) { What is the scope // work of LOCK? } 14
  • 16. DO NOT synchronize on ReentrantLock final Lock lock = new ReentrantLock(); synchronized( lock ) { Probably not what // work you meant here } final Lock lock = new ReentrantLock(); lock.lock(); Probably should try { be this instead // ... } finally { lock.unlock(); } 15
  • 17. What should I lock on? // The field you are protecting private final Map map = ... synchronized(map) { // ...access map } // Or an explicit lock object private final Object lock = new Object(); synchronized(lock) { // ... modify state } 16
  • 19. Inconsistent Synchronization public class SomeData { private final Map data = new HashMap(); public void put(String key, String value) { synchronized(data) { data.put(key, value); Modified under synchronization } } public String get(String key) { return data.get(key); Read without synchronization } } 18
  • 20. Double-checked locking public final class Singleton { private static Singleton instance; public static Singleton getInstance() { if(instance == null) { Attempt to avoid synchronization synchronized(Singleton.class) { if(instance == null) { instance = new Singleton(); } } } return instance; } } 19
  • 21. Double-checked locking public final class Singleton { private static Singleton instance; public static Singleton getInstance() { if(instance == null) { READ synchronized(Singleton.class) { if(instance == null) { READ instance = new Singleton(); WRITE } } } return instance; } } 19
  • 22. Double-checked locking - volatile public class Singleton { private static volatile Singleton instance; public static Singleton getInstance() { if(instance == null) { synchronized(Singleton.class) { if(instance == null) { instance = new Singleton(); } } } return INSTANCE; } 20
  • 23. Double-checked locking - initialize on demand public class Singleton { private static class SingletonHolder { private static final Singleton instance = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.instance; } } 21
  • 24. Racy single-check public final class String { private int hash; // default to 0 private final char[] value; // immutable public int hashCode() { int h = hash; if(h == 0) { // ... compute value for h from data hash = h; } return h; } } 22
  • 25. volatile arrays public final class VolatileArray { private volatile boolean[] vals; public void flip(int i) { vals[i] = true; Is the value of vals[i] } visible to other threads? public boolean flipped(int i) { return vals[i]; } } 23
  • 26. Atomicity 24
  • 27. Volatile counter public class Counter { private volatile int count; public int next() { return count++; Looks atomic to me! } } 25
  • 28. AtomicInteger counter public class Counter { private final AtomicInteger count = new AtomicInteger(); public int next() { Really atomic by return count.getAndIncrement(); encapsulating } multiple actions } 26
  • 29. Composing atomic actions public Object putIfAbsent( Hashtable table, Object key, Object value) { Hashtable is thread-safe if(table.containsKey(key)) { READ // already present, return existing value return table.get(key); READ } else { // doesn’t exist, create and return new value table.put(key, value); WRITE return value; } } 27
  • 30. Composing atomic actions public Object putIfAbsent( Hashtable table, Object key, Object value) { Hashtable is thread-safe if(table.containsKey(key)) { READ // already present, return existing value return table.get(key); READ } else { // doesn’t exist, create and return new value table.put(key, value); WRITE return value; } } 27
  • 31. Participate in lock public Object putIfAbsent( Hashtable table, Object key, Object value) { synchronized(table) { Protect with synchronization if(table.containsKey(key)) { return table.get(key); } else { table.put(key, value); return value; } } } 28
  • 32. Encapsulated compound actions public Object putIfAbsent( ConcurrentHashMap table, Object key, Object value) { table.putIfAbsent(key, value); } 29
  • 33. Assignment of 64 bit values public class LongAssignment { private long x; public void setLong(long val) { x = val; Looks atomic to me - } but is it? } 30
  • 34. Assignment of 64 bit values - volatile public class LongAssignment { private volatile long x; public void setLong(long val) { x = val; } } 31
  • 35. Safe publication Intentionally left blank. 32
  • 36. Listener in constructor public interface DispatchListener { void newFare(Customer customer); } public class Taxi implements DispatchListener { public Taxi(Dispatcher dispatcher) { dispatcher.registerListener(this); We just published a // other initialization reference to this - oops! } public void newFare(Customer customer) { // go to new customer's location } } 33
  • 37. Starting thread in constructor public class Cache { private final Thread cleanerThread; public Cache() { this escapes again! cleanerThread = new Thread(new Cleaner(this)); cleanerThread.start(); } // Cleaner calls back to this method public void cleanup() { // clean up Cache } } 34
  • 38. Static factory method public class Cache { // ... public static Cache newCache() { Cache cache = new Cache(); cache.startCleanerThread(); return cache; } } 35
  • 39. Coordination > Threads > wait/notify 36
  • 40. Threads > DO NOT: • Call Thread.stop() • Call Thread.suspend() or Thread.resume() • Call Thread.destroy() • Call Thread.run() • Use ThreadGroups 37
  • 41. wait/notify // Thread 1 synchronized(lock) { You must synchronize. while(! someCondition()) { Always wait in a loop. lock.wait(); } } // Thread 2 synchronized(lock) { Synchronize here too. satisfyCondition(); Update condition! lock.notifyAll(); } 38
  • 42. Performance > Deadlock > Spin wait > Lock contention 39
  • 43. Deadlock // Thread 1 synchronized(lock1) { synchronized(lock2) { Classic deadlock. // stuff } } // Thread 2 synchronized(lock2) { synchronized(lock1) { // stuff } } 40
  • 44. Deadlock avoidance > Lock splitting > Lock ordering > Lock timeout > tryLock 41
  • 45. Spin wait // Not efficient private volatile boolean flag = false; public void waitTillChange() { while(! flag) { Spin on flag, Thread.sleep(100); waiting for change } } public void change() { flag = true; } 42
  • 46. Replace with wait/notify private final Object lock = new Object(); private boolean flag = false; public void waitTillChange() { synchronized(lock) { while(! flag) Wait/notify is far more lock.wait(); efficient than spin wait. } } public void change() { synchronized(lock) { flag = true; lock.notifyAll(); } } 43
  • 47. Lock contention x Hash f(x) Bucket 0 Bucket 1 Bucket 2 Bucket 3 44
  • 48. Lock striping x Hash g(x) Hash f(x) Hash f(x) Bucket 0 Bucket 1 Bucket 0 Bucket 1 45
  • 49. Final Exam public class StatisticsImpl implements Statistics, StatisticsImplementor { private long queryExecutionCount; public synchronized void queryExecuted(String hql, int rows, long time) { queryExecutionCount++; // ... other stat collection } public long getQueryExecutionCount() { return queryExecutionCount; } public synchronized void clear() { queryExecutionCount = 0; // ... clear all other stats } } 46
  • 50. Final Exam public class StatisticsImpl implements Statistics, StatisticsImplementor { private long queryExecutionCount; public synchronized void queryExecuted(String hql, int rows, long time) { queryExecutionCount++; // ... other stat collection } public long getQueryExecutionCount() { return queryExecutionCount; Read of shared value } without synchronization public synchronized void clear() { queryExecutionCount = 0; // ... clear all other stats } } 46
  • 51. Final Exam public class StatisticsImpl implements Statistics, StatisticsImplementor { private long queryExecutionCount; public synchronized void queryExecuted(String hql, int rows, long time) { queryExecutionCount++; // ... other stat collection } public long getQueryExecutionCount() { return queryExecutionCount; Read of shared value Non-atomic read } without synchronization of long value public synchronized void clear() { queryExecutionCount = 0; // ... clear all other stats } } 46
  • 52. Final Exam public class StatisticsImpl implements Statistics, StatisticsImplementor { private long queryExecutionCount; public synchronized void queryExecuted(String hql, int rows, long time) { queryExecutionCount++; // ... other stat collection } public long getQueryExecutionCount() { return queryExecutionCount; Read of shared value Non-atomic read } without synchronization of long value public synchronized void clear() { queryExecutionCount = 0; Race condition if reading stat and // ... clear all other stats clearing - could be compound action } } 46
  • 53. Final Exam public class StatisticsImpl implements Statistics, StatisticsImplementor { private long queryExecutionCount; public synchronized void queryExecuted(String hql, int rows, long time) { Single shared lock for ALL stat values queryExecutionCount++; // ... other stat collection } public long getQueryExecutionCount() { return queryExecutionCount; Read of shared value Non-atomic read } without synchronization of long value public synchronized void clear() { queryExecutionCount = 0; Race condition if reading stat and // ... clear all other stats clearing - could be compound action } } 46
  • 54. Alex Miller Terracotta Blog: http://tech.puredanger.com Twitter: @puredanger