SlideShare una empresa de Scribd logo
1 de 57
Descargar para leer sin conexión
Java Concurrency
        Gotchas


           Alex Miller
Questions to answer

• What are common concurrency problems?
• Why are they problems?
• How do I detect these problems?
• How to I correct these problems?
Areas of Focus

• Shared Data
• Coordination
• Performance
Areas of Focus


                 {
                     • Locking
• Shared Data        • Visibility
                     • Atomicity
• Coordination
                     • Safe Publication
• Performance
Unprotected Field
     Access

              A



What happens if we modify data
      without locking?
Writer




Readers
          Shared state
Locking


  A
Shared 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 {
      return FORMAT.parse(str);
    }                ...and this mutates it outside synchronization


    public static void main(String arg[])
    throws Exception {
      MutableStatics.parse(“Jan 1, 2000”);
    }
}
Shared 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[])
    throws Exception {
      MutableStatics.parse(“Jan 1, 2000”);
    }
}
Shared mutable statics -
          ThreadLocal
public class MutableStatics {
  private static final ThreadLocal<DateFormat> FORMAT
     = new ThreadLocal<DateFormat>() {
       @Override protected DateFormat initialValue() {
         return DateFormat.getDateInstance(
                                    DateFormat.MEDIUM);
       }
  };

    public static Date parse(String str)
    throws ParseException {
      return FORMAT.get().parse(str);
    }
}
Common JDK Examples

Danger!        Safe

• DateFormat   • Random
• Calendar     • Pattern
• Matcher
Synchronization

private int myField;

synchronized( What goes here? ) {
  myField = 0;
}
DO NOT:
      synchronize on null
MyObject obj = null;

synchronized( obj ) { NullPointerException!
  // work
}
DO NOT:
                change instance
MyObject obj = new MyObject();

synchronized( obj ) {
  obj = new MyObject();
    no longer synchronizing
        on same object!
}
DO NOT:
  synch on string literals
private static final String LOCK = “LOCK”;
synchronized( LOCK ) {
  // work
                      What is the scope of LOCK?
}
DO NOT:
synch on autoboxed vals
private static final Integer LOCK = 0;
synchronized( LOCK ) { What is the scope of LOCK?
  // work
}
DO NOT:
synch on ReentrantLock
Lock lock = new ReentrantLock();
synchronized(lock) {
  // ...    Probably not what you meant here
}


Lock lock = new ReentrantLock();
lock.lock();
                  Probably more like this...
try {
  // ...
} finally {
  lock.unlock();
}
What should I lock on?
// The field you’re protecting
private final Map map = ...
synchronized(map) {
  // ...access map
}


// Explicit lock object
private final Object lock = new Object();
synchronized(lock) {
  // ...modify state
}
Visibility
Visibility problems
int x = 5;

Thread 1:
if(x == 5) {
   x = 10;
}

               Thread 2:
               System.out.println(x);
Visibility problems
volatile int x = 5;

Thread 1:
if(x == 5) {
   x = 10;
}

                      Thread 2:
                      System.out.println(x);
Inconsistent
           Synchronization
public class SomeData {
  private final Map data = new HashMap();

    public void set(String key, String value) {
      synchronized(data) {      Protecting writes
        data.put(key, value);
      }
    }

    public String get(String key) {
      return data.get(key);      ...but not reads
    }
}
Double-checked locking
public 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;
    }
}
Double-checked locking
public 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;
    }
}
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;
    }
}
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;
    }
}
volatile arrays
public final class VolatileArray {

    private volatile boolean[] vals;

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

    public boolean flipped(int i) {
      return vals[i];
    }
}
Atomicity
Volatile counter
public class Counter {

    private volatile int count;

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

    private AtomicInteger count =
      new AtomicInteger();

    public int next() {
      return count.getAndIncrement();
    }                        Really atomic via
}                                encapsulation over
                                 multiple actions
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
      table.get(key);                            READ
      return null;

    } else {
      // doesn't exist, create new value         WRITE
      return table.put(key, value);
    }
}
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
      table.get(key);                            READ
      return null;

    } else {
      // doesn't exist, create new value         WRITE
      return table.put(key, value);
    }
}
Participate in lock
public Object putIfAbsent(
  Hashtable table, Object key, Object value) {
         Hashtable is
         thread-safe

    synchronized(table) {
      if(table.containsKey(key)) {
        table.get(key);
        return null;
      } else {
        return table.put(key, value);
      }
    }
}
Encapsulated compound
            actions
public Object putIfAbsent(
  ConcurrentHashMap table, Object key, Object value) {

    return table.putIfAbsent(key, value);
}
                                   Encpasulation FTW!
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?
}
Assignment of
    64 bit values - volatile
public class LongAssignment {

    private volatile long x;

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

}
Safe publication
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
    }
}
Starting thread
             in constructor
public class Cache {

    private final Thread cleanerThread;

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

    // Clean will call back to this method
    public void cleanup() {
      // clean up Cache
    }
}
Static factory method
public class Cache {
  // ...

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

• Shared Data
• Coordination
• Performance
                 {   • Threads
                     • Wait/notify
Threads
• THOU SHALT NOT:
 • call Thread.stop() All monitors unlocked by ThreadDeath


 • call Thread.suspend() or Thread.resume()
                                      Can lead to deadlock



 • call Thread.destroy()     Not implemented (or safe)


 • call Thread.run()   Wonʼt start Thread! Still in caller Thread.


 • use ThreadGroups        Use a ThreadPoolExecutor instead.
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();
  lock.notifyAll();
}
Condition is similar
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();

public void waitTillChange() {
  lock.lock();
  try {
    while(! someCondition()) condition.await();
  } finally {
    lock.unlock();
  }                                   Condition is more
                                      flexible than wait/notify.
}
public void change() {
  lock.lock();
  try {
    satisfyCondition();
    condition.signalAll();
  } finally { lock.unlock(); } }
Areas of Focus

• Shared Data
• Coordination       • Deadlock
• Performance    {   • Spin wait
                     • Thread contention
Deadlock
// Thread 1
synchronized(lock1) {
  synchronized(lock2) {
    // stuff
  }
}
                          Classic deadlock.
// Thread 2
synchronized(lock2) {
  synchronized(lock1) {
    // stuff
  }
}
Deadlock avoidance

• Lock splitting
• Lock ordering
• Lock timeout
• tryLock
Spin wait
// Not efficient
private volatile boolean flag = false;

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

public void change() {
  flag = true;
}
Replace with Condition
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
private boolean flag = false;

public void waitTillChange() {
  lock.lock();
  try {
    while(! flag) condition.await();
  } finally {
    lock.unlock();                     Better but longer.
  }
}
public void change() {
  lock.lock();
  try {
    flag = true;
    condition.signalAll();
  } finally { lock.unlock(); } }
CountDownLatch
private final CountDownLatch latch =
  new CountDownLatch(1);

public void waitTillChange() {
  latch.await();
}

public void change() {
  latch.countDown();
                                  Coordination classes
}
                                  like CountDownLatch
                                  and CyclicBarrier cover
                                  many common uses
                                  better than Condition.
Lock contention
                         x




                      Hash f(x)




Bucket 0   Bucket 1           Bucket 2   Bucket 3
Lock striping
                                 x




                              Hash g(x)




           Hash f(x)                                 Hash f(x)




Bucket 0           Bucket 1               Bucket 0           Bucket 1
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
    }
}
Final Exam
public class StatisticsImpl implements Statistics,
StatisticsImplementor {
  private long queryExecutionCount;
                     Single shared lock for ALL stat values
    public synchronized void queryExecuted(
                      String hql, int rows, long time) {
      queryExecutionCount++;
      // ... other stat collection
    }

    public long getQueryExecutionCount() {
      return queryExecutionCount;
                                  Read shared value             Non-atomic read
    }
                                            w/o synchronization of long value
    public synchronized void clear() {
      queryExecutionCount = 0;
                                     Race condition if reading
      // ... clear all other stats   stat and clearing
    }
}
Thanks...
Twitter       http://twitter.com/puredanger
Blog          http://tech.puredanger.com
Concurrency   http://concurrency.tumblr.com
links
              http://refcardz.dzone.com/refcardz/
Refcard
              core-java-concurrency
Slides        http://slideshare.net/alexmiller

Más contenido relacionado

La actualidad más candente

Angular js routing options
Angular js routing optionsAngular js routing options
Angular js routing optionsNir Kaufman
 
Spring Boot Actuator 2.0 & Micrometer
Spring Boot Actuator 2.0 & MicrometerSpring Boot Actuator 2.0 & Micrometer
Spring Boot Actuator 2.0 & MicrometerToshiaki Maki
 
L'API Collector dans tous ses états
L'API Collector dans tous ses étatsL'API Collector dans tous ses états
L'API Collector dans tous ses étatsJosé Paumard
 
How and Why GraalVM is quickly becoming relevant for developers (ACEs@home - ...
How and Why GraalVM is quickly becoming relevant for developers (ACEs@home - ...How and Why GraalVM is quickly becoming relevant for developers (ACEs@home - ...
How and Why GraalVM is quickly becoming relevant for developers (ACEs@home - ...Lucas Jellema
 
Deep Dive into Building Streaming Applications with Apache Pulsar
Deep Dive into Building Streaming Applications with Apache Pulsar Deep Dive into Building Streaming Applications with Apache Pulsar
Deep Dive into Building Streaming Applications with Apache Pulsar Timothy Spann
 
Hadoop REST API Security with Apache Knox Gateway
Hadoop REST API Security with Apache Knox GatewayHadoop REST API Security with Apache Knox Gateway
Hadoop REST API Security with Apache Knox GatewayDataWorks Summit
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with SpringJoshua Long
 
Graal and Truffle: One VM to Rule Them All
Graal and Truffle: One VM to Rule Them AllGraal and Truffle: One VM to Rule Them All
Graal and Truffle: One VM to Rule Them AllThomas Wuerthinger
 
Event Driven Systems with Spring Boot, Spring Cloud Streams and Kafka
Event Driven Systems with Spring Boot, Spring Cloud Streams and KafkaEvent Driven Systems with Spring Boot, Spring Cloud Streams and Kafka
Event Driven Systems with Spring Boot, Spring Cloud Streams and KafkaVMware Tanzu
 
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition! Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition! Michel Schudel
 
Understanding the Single Thread Event Loop
Understanding the Single Thread Event LoopUnderstanding the Single Thread Event Loop
Understanding the Single Thread Event LoopTorontoNodeJS
 
Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1Toshiaki Maki
 
Polylog: A Log-Based Architecture for Distributed Systems
Polylog: A Log-Based Architecture for Distributed SystemsPolylog: A Log-Based Architecture for Distributed Systems
Polylog: A Log-Based Architecture for Distributed SystemsLongtail Video
 
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현NAVER Engineering
 
Discover Quarkus and GraalVM
Discover Quarkus and GraalVMDiscover Quarkus and GraalVM
Discover Quarkus and GraalVMRomain Schlick
 
GraalVM Overview Compact version
GraalVM Overview Compact versionGraalVM Overview Compact version
GraalVM Overview Compact versionscalaconfjp
 

La actualidad más candente (20)

Angular js routing options
Angular js routing optionsAngular js routing options
Angular js routing options
 
Spring Boot Actuator 2.0 & Micrometer
Spring Boot Actuator 2.0 & MicrometerSpring Boot Actuator 2.0 & Micrometer
Spring Boot Actuator 2.0 & Micrometer
 
Completable future
Completable futureCompletable future
Completable future
 
L'API Collector dans tous ses états
L'API Collector dans tous ses étatsL'API Collector dans tous ses états
L'API Collector dans tous ses états
 
How and Why GraalVM is quickly becoming relevant for developers (ACEs@home - ...
How and Why GraalVM is quickly becoming relevant for developers (ACEs@home - ...How and Why GraalVM is quickly becoming relevant for developers (ACEs@home - ...
How and Why GraalVM is quickly becoming relevant for developers (ACEs@home - ...
 
Deep Dive into Building Streaming Applications with Apache Pulsar
Deep Dive into Building Streaming Applications with Apache Pulsar Deep Dive into Building Streaming Applications with Apache Pulsar
Deep Dive into Building Streaming Applications with Apache Pulsar
 
Kafka Security
Kafka SecurityKafka Security
Kafka Security
 
Hadoop REST API Security with Apache Knox Gateway
Hadoop REST API Security with Apache Knox GatewayHadoop REST API Security with Apache Knox Gateway
Hadoop REST API Security with Apache Knox Gateway
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
Graal and Truffle: One VM to Rule Them All
Graal and Truffle: One VM to Rule Them AllGraal and Truffle: One VM to Rule Them All
Graal and Truffle: One VM to Rule Them All
 
Event Driven Systems with Spring Boot, Spring Cloud Streams and Kafka
Event Driven Systems with Spring Boot, Spring Cloud Streams and KafkaEvent Driven Systems with Spring Boot, Spring Cloud Streams and Kafka
Event Driven Systems with Spring Boot, Spring Cloud Streams and Kafka
 
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition! Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
 
Understanding the Single Thread Event Loop
Understanding the Single Thread Event LoopUnderstanding the Single Thread Event Loop
Understanding the Single Thread Event Loop
 
Terraform
TerraformTerraform
Terraform
 
Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1
 
Polylog: A Log-Based Architecture for Distributed Systems
Polylog: A Log-Based Architecture for Distributed SystemsPolylog: A Log-Based Architecture for Distributed Systems
Polylog: A Log-Based Architecture for Distributed Systems
 
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
[네이버오픈소스세미나] Pinpoint를 이용해서 서버리스 플랫폼 Apache Openwhisk 트레이싱하기 - 오승현
 
Discover Quarkus and GraalVM
Discover Quarkus and GraalVMDiscover Quarkus and GraalVM
Discover Quarkus and GraalVM
 
GraalVM Overview Compact version
GraalVM Overview Compact versionGraalVM Overview Compact version
GraalVM Overview Compact version
 
OAuth 2.0
OAuth 2.0OAuth 2.0
OAuth 2.0
 

Destacado

Effective java - concurrency
Effective java - concurrencyEffective java - concurrency
Effective java - concurrencyfeng lee
 
Dzone core java concurrency -_
Dzone core java concurrency -_Dzone core java concurrency -_
Dzone core java concurrency -_Surendra Sirvi
 
[Java concurrency]01.thread management
[Java concurrency]01.thread management[Java concurrency]01.thread management
[Java concurrency]01.thread managementxuehan zhu
 
Caching In The Cloud
Caching In The CloudCaching In The Cloud
Caching In The CloudAlex Miller
 
Innovative Software
Innovative SoftwareInnovative Software
Innovative SoftwareAlex Miller
 
Releasing Relational Data to the Semantic Web
Releasing Relational Data to the Semantic WebReleasing Relational Data to the Semantic Web
Releasing Relational Data to the Semantic WebAlex Miller
 
Scaling Your Cache
Scaling Your CacheScaling Your Cache
Scaling Your CacheAlex Miller
 
Stream Execution with Clojure and Fork/join
Stream Execution with Clojure and Fork/joinStream Execution with Clojure and Fork/join
Stream Execution with Clojure and Fork/joinAlex Miller
 
Project Fortress
Project FortressProject Fortress
Project FortressAlex Miller
 
Groovy concurrency
Groovy concurrencyGroovy concurrency
Groovy concurrencyAlex Miller
 
Scaling Hibernate with Terracotta
Scaling Hibernate with TerracottaScaling Hibernate with Terracotta
Scaling Hibernate with TerracottaAlex Miller
 
Working With Concurrency In Java 8
Working With Concurrency In Java 8Working With Concurrency In Java 8
Working With Concurrency In Java 8Heartin Jacob
 
Java Concurrency in Practice
Java Concurrency in PracticeJava Concurrency in Practice
Java Concurrency in PracticeAlina Dolgikh
 
Java Concurrency, Memory Model, and Trends
Java Concurrency, Memory Model, and TrendsJava Concurrency, Memory Model, and Trends
Java Concurrency, Memory Model, and TrendsCarol McDonald
 
Cracking clojure
Cracking clojureCracking clojure
Cracking clojureAlex Miller
 
Clojure: The Art of Abstraction
Clojure: The Art of AbstractionClojure: The Art of Abstraction
Clojure: The Art of AbstractionAlex Miller
 
Modern Java Concurrency
Modern Java ConcurrencyModern Java Concurrency
Modern Java ConcurrencyBen Evans
 
Lessons from the intelligent investor
Lessons from the intelligent investorLessons from the intelligent investor
Lessons from the intelligent investorPamela Paikea
 

Destacado (20)

Effective java - concurrency
Effective java - concurrencyEffective java - concurrency
Effective java - concurrency
 
Dzone core java concurrency -_
Dzone core java concurrency -_Dzone core java concurrency -_
Dzone core java concurrency -_
 
[Java concurrency]01.thread management
[Java concurrency]01.thread management[Java concurrency]01.thread management
[Java concurrency]01.thread management
 
Blogging ZOMG
Blogging ZOMGBlogging ZOMG
Blogging ZOMG
 
Caching In The Cloud
Caching In The CloudCaching In The Cloud
Caching In The Cloud
 
Innovative Software
Innovative SoftwareInnovative Software
Innovative Software
 
Releasing Relational Data to the Semantic Web
Releasing Relational Data to the Semantic WebReleasing Relational Data to the Semantic Web
Releasing Relational Data to the Semantic Web
 
Scaling Your Cache
Scaling Your CacheScaling Your Cache
Scaling Your Cache
 
Cold Hard Cache
Cold Hard CacheCold Hard Cache
Cold Hard Cache
 
Stream Execution with Clojure and Fork/join
Stream Execution with Clojure and Fork/joinStream Execution with Clojure and Fork/join
Stream Execution with Clojure and Fork/join
 
Project Fortress
Project FortressProject Fortress
Project Fortress
 
Groovy concurrency
Groovy concurrencyGroovy concurrency
Groovy concurrency
 
Scaling Hibernate with Terracotta
Scaling Hibernate with TerracottaScaling Hibernate with Terracotta
Scaling Hibernate with Terracotta
 
Working With Concurrency In Java 8
Working With Concurrency In Java 8Working With Concurrency In Java 8
Working With Concurrency In Java 8
 
Java Concurrency in Practice
Java Concurrency in PracticeJava Concurrency in Practice
Java Concurrency in Practice
 
Java Concurrency, Memory Model, and Trends
Java Concurrency, Memory Model, and TrendsJava Concurrency, Memory Model, and Trends
Java Concurrency, Memory Model, and Trends
 
Cracking clojure
Cracking clojureCracking clojure
Cracking clojure
 
Clojure: The Art of Abstraction
Clojure: The Art of AbstractionClojure: The Art of Abstraction
Clojure: The Art of Abstraction
 
Modern Java Concurrency
Modern Java ConcurrencyModern Java Concurrency
Modern Java Concurrency
 
Lessons from the intelligent investor
Lessons from the intelligent investorLessons from the intelligent investor
Lessons from the intelligent investor
 

Similar a Java Concurrency Gotchas

Java Concurrency Gotchas
Java Concurrency GotchasJava Concurrency Gotchas
Java Concurrency GotchasAlex Miller
 
Javaoneconcurrencygotchas 090610192215 Phpapp02
Javaoneconcurrencygotchas 090610192215 Phpapp02Javaoneconcurrencygotchas 090610192215 Phpapp02
Javaoneconcurrencygotchas 090610192215 Phpapp02Tarun Kumar
 
第1回 チキチキ『( ゜ェ゜)・;'.、ゴフッ』 - シングルトンパターン(Java)
第1回 チキチキ『( ゜ェ゜)・;'.、ゴフッ』 - シングルトンパターン(Java)第1回 チキチキ『( ゜ェ゜)・;'.、ゴフッ』 - シングルトンパターン(Java)
第1回 チキチキ『( ゜ェ゜)・;'.、ゴフッ』 - シングルトンパターン(Java)潤一 加藤
 
.NET Multithreading and File I/O
.NET Multithreading and File I/O.NET Multithreading and File I/O
.NET Multithreading and File I/OJussi Pohjolainen
 
From Runnable and synchronized To atomically() and parallel()
From Runnable and synchronized To atomically() and parallel()From Runnable and synchronized To atomically() and parallel()
From Runnable and synchronized To atomically() and parallel()José Paumard
 
3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в JavaDEVTYPE
 
Use of Apache Commons and Utilities
Use of Apache Commons and UtilitiesUse of Apache Commons and Utilities
Use of Apache Commons and UtilitiesPramod Kumar
 
Java 5 concurrency
Java 5 concurrencyJava 5 concurrency
Java 5 concurrencypriyank09
 
AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokusHamletDRC
 
Java осень 2012 лекция 2
Java осень 2012 лекция 2Java осень 2012 лекция 2
Java осень 2012 лекция 2Technopark
 
Ast transformations
Ast transformationsAst transformations
Ast transformationsHamletDRC
 
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
 
Java concurrency begining
Java concurrency   beginingJava concurrency   begining
Java concurrency beginingmaksym220889
 
What’s new in C# 6
What’s new in C# 6What’s new in C# 6
What’s new in C# 6Fiyaz Hasan
 
using the code below create a method called getCollisionCount that w.pdf
using the code below create a method called getCollisionCount that w.pdfusing the code below create a method called getCollisionCount that w.pdf
using the code below create a method called getCollisionCount that w.pdfamirthagiftsmadurai
 

Similar a Java Concurrency Gotchas (20)

Java Concurrency Gotchas
Java Concurrency GotchasJava Concurrency Gotchas
Java Concurrency Gotchas
 
Javaoneconcurrencygotchas 090610192215 Phpapp02
Javaoneconcurrencygotchas 090610192215 Phpapp02Javaoneconcurrencygotchas 090610192215 Phpapp02
Javaoneconcurrencygotchas 090610192215 Phpapp02
 
Concurrency gotchas
Concurrency gotchasConcurrency gotchas
Concurrency gotchas
 
第1回 チキチキ『( ゜ェ゜)・;'.、ゴフッ』 - シングルトンパターン(Java)
第1回 チキチキ『( ゜ェ゜)・;'.、ゴフッ』 - シングルトンパターン(Java)第1回 チキチキ『( ゜ェ゜)・;'.、ゴフッ』 - シングルトンパターン(Java)
第1回 チキチキ『( ゜ェ゜)・;'.、ゴフッ』 - シングルトンパターン(Java)
 
.NET Multithreading and File I/O
.NET Multithreading and File I/O.NET Multithreading and File I/O
.NET Multithreading and File I/O
 
From Runnable and synchronized To atomically() and parallel()
From Runnable and synchronized To atomically() and parallel()From Runnable and synchronized To atomically() and parallel()
From Runnable and synchronized To atomically() and parallel()
 
Java concurrency
Java concurrencyJava concurrency
Java concurrency
 
3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java
 
Use of Apache Commons and Utilities
Use of Apache Commons and UtilitiesUse of Apache Commons and Utilities
Use of Apache Commons and Utilities
 
Java 5 concurrency
Java 5 concurrencyJava 5 concurrency
Java 5 concurrency
 
Scala in practice
Scala in practiceScala in practice
Scala in practice
 
AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokus
 
Java осень 2012 лекция 2
Java осень 2012 лекция 2Java осень 2012 лекция 2
Java осень 2012 лекция 2
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 
Thread
ThreadThread
Thread
 
04 threads
04 threads04 threads
04 threads
 
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
 
Java concurrency begining
Java concurrency   beginingJava concurrency   begining
Java concurrency begining
 
What’s new in C# 6
What’s new in C# 6What’s new in C# 6
What’s new in C# 6
 
using the code below create a method called getCollisionCount that w.pdf
using the code below create a method called getCollisionCount that w.pdfusing the code below create a method called getCollisionCount that w.pdf
using the code below create a method called getCollisionCount that w.pdf
 

Más de Alex Miller

Clojure/West Overview (12/1/11)
Clojure/West Overview (12/1/11)Clojure/West Overview (12/1/11)
Clojure/West Overview (12/1/11)Alex Miller
 
Concurrent Stream Processing
Concurrent Stream ProcessingConcurrent Stream Processing
Concurrent Stream ProcessingAlex Miller
 
Tree Editing with Zippers
Tree Editing with ZippersTree Editing with Zippers
Tree Editing with ZippersAlex Miller
 
Scaling Your Cache And Caching At Scale
Scaling Your Cache And Caching At ScaleScaling Your Cache And Caching At Scale
Scaling Your Cache And Caching At ScaleAlex Miller
 
Marshmallow Test
Marshmallow TestMarshmallow Test
Marshmallow TestAlex Miller
 
Strange Loop Conference 2009
Strange Loop Conference 2009Strange Loop Conference 2009
Strange Loop Conference 2009Alex Miller
 
Java Collections API
Java Collections APIJava Collections API
Java Collections APIAlex Miller
 
Java Concurrency Idioms
Java Concurrency IdiomsJava Concurrency Idioms
Java Concurrency IdiomsAlex Miller
 
Design Patterns Reconsidered
Design Patterns ReconsideredDesign Patterns Reconsidered
Design Patterns ReconsideredAlex Miller
 
Exploring Terracotta
Exploring TerracottaExploring Terracotta
Exploring TerracottaAlex Miller
 
Actor Concurrency
Actor ConcurrencyActor Concurrency
Actor ConcurrencyAlex Miller
 

Más de Alex Miller (12)

Clojure/West Overview (12/1/11)
Clojure/West Overview (12/1/11)Clojure/West Overview (12/1/11)
Clojure/West Overview (12/1/11)
 
Concurrent Stream Processing
Concurrent Stream ProcessingConcurrent Stream Processing
Concurrent Stream Processing
 
Tree Editing with Zippers
Tree Editing with ZippersTree Editing with Zippers
Tree Editing with Zippers
 
Scaling Your Cache And Caching At Scale
Scaling Your Cache And Caching At ScaleScaling Your Cache And Caching At Scale
Scaling Your Cache And Caching At Scale
 
Marshmallow Test
Marshmallow TestMarshmallow Test
Marshmallow Test
 
Strange Loop Conference 2009
Strange Loop Conference 2009Strange Loop Conference 2009
Strange Loop Conference 2009
 
Java Collections API
Java Collections APIJava Collections API
Java Collections API
 
Java Concurrency Idioms
Java Concurrency IdiomsJava Concurrency Idioms
Java Concurrency Idioms
 
Design Patterns Reconsidered
Design Patterns ReconsideredDesign Patterns Reconsidered
Design Patterns Reconsidered
 
Java 7 Preview
Java 7 PreviewJava 7 Preview
Java 7 Preview
 
Exploring Terracotta
Exploring TerracottaExploring Terracotta
Exploring Terracotta
 
Actor Concurrency
Actor ConcurrencyActor Concurrency
Actor Concurrency
 

Último

2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Zilliz
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...apidays
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...Zilliz
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbuapidays
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusZilliz
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024The Digital Insurer
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 

Último (20)

2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 

Java Concurrency Gotchas

  • 1. Java Concurrency Gotchas Alex Miller
  • 2. Questions to answer • What are common concurrency problems? • Why are they problems? • How do I detect these problems? • How to I correct these problems?
  • 3. Areas of Focus • Shared Data • Coordination • Performance
  • 4. Areas of Focus { • Locking • Shared Data • Visibility • Atomicity • Coordination • Safe Publication • Performance
  • 5. Unprotected Field Access A What happens if we modify data without locking?
  • 6.
  • 7. Writer Readers Shared state
  • 9. Shared 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 { return FORMAT.parse(str); } ...and this mutates it outside synchronization public static void main(String arg[]) throws Exception { MutableStatics.parse(“Jan 1, 2000”); } }
  • 10. Shared 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[]) throws Exception { MutableStatics.parse(“Jan 1, 2000”); } }
  • 11. Shared mutable statics - ThreadLocal public class MutableStatics { private static final ThreadLocal<DateFormat> FORMAT = new ThreadLocal<DateFormat>() { @Override protected DateFormat initialValue() { return DateFormat.getDateInstance( DateFormat.MEDIUM); } }; public static Date parse(String str) throws ParseException { return FORMAT.get().parse(str); } }
  • 12. Common JDK Examples Danger! Safe • DateFormat • Random • Calendar • Pattern • Matcher
  • 13. Synchronization private int myField; synchronized( What goes here? ) { myField = 0; }
  • 14. DO NOT: synchronize on null MyObject obj = null; synchronized( obj ) { NullPointerException! // work }
  • 15. DO NOT: change instance MyObject obj = new MyObject(); synchronized( obj ) { obj = new MyObject(); no longer synchronizing on same object! }
  • 16. DO NOT: synch on string literals private static final String LOCK = “LOCK”; synchronized( LOCK ) { // work What is the scope of LOCK? }
  • 17. DO NOT: synch on autoboxed vals private static final Integer LOCK = 0; synchronized( LOCK ) { What is the scope of LOCK? // work }
  • 18. DO NOT: synch on ReentrantLock Lock lock = new ReentrantLock(); synchronized(lock) { // ... Probably not what you meant here } Lock lock = new ReentrantLock(); lock.lock(); Probably more like this... try { // ... } finally { lock.unlock(); }
  • 19. What should I lock on? // The field you’re protecting private final Map map = ... synchronized(map) { // ...access map } // Explicit lock object private final Object lock = new Object(); synchronized(lock) { // ...modify state }
  • 21. Visibility problems int x = 5; Thread 1: if(x == 5) { x = 10; } Thread 2: System.out.println(x);
  • 22. Visibility problems volatile int x = 5; Thread 1: if(x == 5) { x = 10; } Thread 2: System.out.println(x);
  • 23. Inconsistent Synchronization public class SomeData { private final Map data = new HashMap(); public void set(String key, String value) { synchronized(data) { Protecting writes data.put(key, value); } } public String get(String key) { return data.get(key); ...but not reads } }
  • 24. Double-checked locking public 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; } }
  • 25. Double-checked locking public 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; } }
  • 26. 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; } }
  • 27. 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; } }
  • 28. volatile arrays public final class VolatileArray { private volatile boolean[] vals; public void flip(int i) { Is the value of vals[i] vals[i] = true; visible to other threads? } public boolean flipped(int i) { return vals[i]; } }
  • 30. Volatile counter public class Counter { private volatile int count; public int next() { return count++; Looks atomic to me! } }
  • 31. AtomicInteger counter public class Counter { private AtomicInteger count = new AtomicInteger(); public int next() { return count.getAndIncrement(); } Really atomic via } encapsulation over multiple actions
  • 32. 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 table.get(key); READ return null; } else { // doesn't exist, create new value WRITE return table.put(key, value); } }
  • 33. 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 table.get(key); READ return null; } else { // doesn't exist, create new value WRITE return table.put(key, value); } }
  • 34. Participate in lock public Object putIfAbsent( Hashtable table, Object key, Object value) { Hashtable is thread-safe synchronized(table) { if(table.containsKey(key)) { table.get(key); return null; } else { return table.put(key, value); } } }
  • 35. Encapsulated compound actions public Object putIfAbsent( ConcurrentHashMap table, Object key, Object value) { return table.putIfAbsent(key, value); } Encpasulation FTW!
  • 36. 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? }
  • 37. Assignment of 64 bit values - volatile public class LongAssignment { private volatile long x; public void setLong(long val) { x = val; } }
  • 39. 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 } }
  • 40. Starting thread in constructor public class Cache { private final Thread cleanerThread; public Cache() { cleanerThread = new Thread(new Cleaner(this)); cleanerThread.start(); this escapes again! } // Clean will call back to this method public void cleanup() { // clean up Cache } }
  • 41. Static factory method public class Cache { // ... public static Cache newCache() { Cache cache = new Cache(); cache.startCleanerThread(); return cache; } }
  • 42. Areas of Focus • Shared Data • Coordination • Performance { • Threads • Wait/notify
  • 44. • THOU SHALT NOT: • call Thread.stop() All monitors unlocked by ThreadDeath • call Thread.suspend() or Thread.resume() Can lead to deadlock • call Thread.destroy() Not implemented (or safe) • call Thread.run() Wonʼt start Thread! Still in caller Thread. • use ThreadGroups Use a ThreadPoolExecutor instead.
  • 45. 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(); lock.notifyAll(); }
  • 46. Condition is similar private final Lock lock = new ReentrantLock(); private final Condition condition = lock.newCondition(); public void waitTillChange() { lock.lock(); try { while(! someCondition()) condition.await(); } finally { lock.unlock(); } Condition is more flexible than wait/notify. } public void change() { lock.lock(); try { satisfyCondition(); condition.signalAll(); } finally { lock.unlock(); } }
  • 47. Areas of Focus • Shared Data • Coordination • Deadlock • Performance { • Spin wait • Thread contention
  • 48. Deadlock // Thread 1 synchronized(lock1) { synchronized(lock2) { // stuff } } Classic deadlock. // Thread 2 synchronized(lock2) { synchronized(lock1) { // stuff } }
  • 49. Deadlock avoidance • Lock splitting • Lock ordering • Lock timeout • tryLock
  • 50. Spin wait // Not efficient private volatile boolean flag = false; public void waitTillChange() { while(! flag) { Thread.sleep(100); Spin on flag, waiting for a change. } } public void change() { flag = true; }
  • 51. Replace with Condition private final Lock lock = new ReentrantLock(); private final Condition condition = lock.newCondition(); private boolean flag = false; public void waitTillChange() { lock.lock(); try { while(! flag) condition.await(); } finally { lock.unlock(); Better but longer. } } public void change() { lock.lock(); try { flag = true; condition.signalAll(); } finally { lock.unlock(); } }
  • 52. CountDownLatch private final CountDownLatch latch = new CountDownLatch(1); public void waitTillChange() { latch.await(); } public void change() { latch.countDown(); Coordination classes } like CountDownLatch and CyclicBarrier cover many common uses better than Condition.
  • 53. Lock contention x Hash f(x) Bucket 0 Bucket 1 Bucket 2 Bucket 3
  • 54. Lock striping x Hash g(x) Hash f(x) Hash f(x) Bucket 0 Bucket 1 Bucket 0 Bucket 1
  • 55. 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 } }
  • 56. Final Exam public class StatisticsImpl implements Statistics, StatisticsImplementor { private long queryExecutionCount; Single shared lock for ALL stat values public synchronized void queryExecuted( String hql, int rows, long time) { queryExecutionCount++; // ... other stat collection } public long getQueryExecutionCount() { return queryExecutionCount; Read shared value Non-atomic read } w/o synchronization of long value public synchronized void clear() { queryExecutionCount = 0; Race condition if reading // ... clear all other stats stat and clearing } }
  • 57. Thanks... Twitter http://twitter.com/puredanger Blog http://tech.puredanger.com Concurrency http://concurrency.tumblr.com links http://refcardz.dzone.com/refcardz/ Refcard core-java-concurrency Slides http://slideshare.net/alexmiller