How not to do Java Concurrency And how to find if you did it wrong Mark Winterrowd 2014-09-30.

Slides:



Advertisements
Similar presentations
Operating Systems: Monitors 1 Monitors (C.A.R. Hoare) higher level construct than semaphores a package of grouped procedures, variables and data i.e. object.
Advertisements

Practice Session 7 Synchronization Liveness Deadlock Starvation Livelock Guarded Methods Model Thread Timing Busy Wait Sleep and Check Wait and Notify.
Concurrency The need for speed. Why concurrency? Moore’s law: 1. The number of components on a chip doubles about every 18 months 2. The speed of computation.
Concurrency 101 Shared state. Part 1: General Concepts 2.
/ PSWLAB Concurrent Bug Patterns and How to Test Them by Eitan Farchi, Yarden Nir, Shmuel Ur published in the proceedings of IPDPS’03 (PADTAD2003)
COS 461 Fall 1997 Concurrent Programming u Traditional programs do one thing at a time. u Concurrent programs do several things at once. u Why do this?
CS 11 java track: lecture 7 This week: Web tutorial:
Oct Ron McFadyen1 Singleton To guarantee that there is at most one instance of a class we can apply the singleton pattern. Singleton Static.
Threading Part 4 CS221 – 4/27/09. The Final Date: 5/7 Time: 6pm Duration: 1hr 50mins Location: EPS 103 Bring: 1 sheet of paper, filled both sides with.
Threading Part 3 CS221 – 4/24/09. Teacher Survey Fill out the survey in next week’s lab You will be asked to assess: – The Course – The Teacher – The.
Threading Part 2 CS221 – 4/22/09. Where We Left Off Simple Threads Program: – Start a worker thread from the Main thread – Worker thread prints messages.
Threads Load new page Page is loading Browser still responds to user (can read pages in other tabs)
Concurrent Processes Lecture 5. Introduction Modern operating systems can handle more than one process at a time System scheduler manages processes and.
Synchronization in Java Nelson Padua-Perez Bill Pugh Department of Computer Science University of Maryland, College Park.
Building Secure Software Chapter 9 Race Conditions.
Synchronization in Java Fawzi Emad Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
1 Sharing Objects – Ch. 3 Visibility What is the source of the issue? Volatile Dekker’s algorithm Publication and Escape Thread Confinement Immutability.
29-Jun-15 Java Concurrency. Definitions Parallel processes—two or more Threads are running simultaneously, on different cores (processors), in the same.
U NIVERSITY OF M ASSACHUSETTS, A MHERST Department of Computer Science Emery Berger University of Massachusetts, Amherst Operating Systems CMPSCI 377 Lecture.
Threads II. Review A thread is a single flow of control through a program Java is multithreaded—several threads may be executing “simultaneously” If you.
More Multithreaded Programming in Java David Meredith Aalborg University.
Threads in Java1 Concurrency Synchronizing threads, thread pools, etc.
ICAPRG301A Week 4Buggy Programming ICAPRG301A Apply introductory programming techniques Program Bugs US Navy Admiral Grace Hopper is often credited with.
Object Oriented Analysis & Design SDL Threads. Contents 2  Processes  Thread Concepts  Creating threads  Critical sections  Synchronizing threads.
Threads. Java Threads A thread is not an object A thread is a flow of control A thread is a series of executed statements A thread is a nested sequence.
Java Threads 11 Threading and Concurrent Programming in Java Introduction and Definitions D.W. Denbo Introduction and Definitions D.W. Denbo.
DEBUGGING. BUG A software bug is an error, flaw, failure, or fault in a computer program or system that causes it to produce an incorrect or unexpected.
1 (Worker Queues) cs What is a Thread Pool? A collection of threads that are created once (e.g. when a server starts) That is, no need to create.
Optimistic Design 1. Guarded Methods Do something based on the fact that one or more objects have particular states  Make a set of purchases assuming.
COMP 111 Threads and concurrency Sept 28, Tufts University Computer Science2 Who is this guy? I am not Prof. Couch Obvious? Sam Guyer New assistant.
Operating Systems ECE344 Ashvin Goel ECE University of Toronto Mutual Exclusion.
Internet Software Development Controlling Threads Paul J Krause.
Producer-Consumer Problem The problem describes two processes, the producer and the consumer, who share a common, fixed-size buffer used as a queue.bufferqueue.
Synchronized and Monitors. synchronized is a Java keyword to denote a block of code which must be executed atomically (uninterrupted). It can be applied.
11/18/20151 Operating Systems Design (CS 423) Elsa L Gunter 2112 SC, UIUC Based on slides by Roy Campbell, Sam.
Kernel Locking Techniques by Robert Love presented by Scott Price.
Java Thread and Memory Model
The Singleton Pattern SE-2811 Dr. Mark L. Hornick 1.
SPL/2010 Guarded Methods and Waiting 1. SPL/2010 Reminder! ● Concurrency problem: asynchronous modifications to object states lead to failure of thread.
CS399 New Beginnings Jonathan Walpole. 2 Concurrent Programming & Synchronization Primitives.
Monitors and Blocking Synchronization Dalia Cohn Alperovich Based on “The Art of Multiprocessor Programming” by Herlihy & Shavit, chapter 8.
Findbugs Tin Bui-Huy September, Content What is bug? What is bug? What is Findbugs? What is Findbugs? How to use Findbugs? How to use Findbugs?
Threads. Objectives You must be able to answer the following questions –What code does a thread execute? –What states can a thread be in? –How does a.
Threads and Singleton. Threads  The JVM allows multiple “threads of execution”  Essentially separate programs running concurrently in one memory space.
U NIVERSITY OF M ASSACHUSETTS A MHERST Department of Computer Science Computer Systems Principles Synchronization Emery Berger and Mark Corner University.
The Singleton Pattern (Creational)
Week 9, Class 3: Java’s Happens-Before Memory Model (Slides used and skipped in class) SE-2811 Slide design: Dr. Mark L. Hornick Content: Dr. Hornick Errors:
Dining Philosophers & Monitors Questions answered in this lecture: How to synchronize dining philosophers? What are monitors and condition variables? What.
Implementing Lock. From the Previous Lecture  The “too much milk” example shows that writing concurrent programs directly with load and store instructions.
CS 151: Object-Oriented Design November 26 Class Meeting Department of Computer Science San Jose State University Fall 2013 Instructor: Ron Mak
Concurrency: Locks and synchronization Slides by Prof. Cox.
Concurrent Programming in Java Based on Notes by J. Johns (based on Java in a Nutshell, Learning Java) Also Java Tutorial, Concurrent Programming in Java.
Lecture 5 Page 1 CS 111 Summer 2013 Bounded Buffers A higher level abstraction than shared domains or simple messages But not quite as high level as RPC.
Thread Pools (Worker Queues) cs
Design Patterns – Chocolate Factory (from Head First Design Patterns)
The Singleton Pattern SE-2811 Dr. Mark L. Hornick.
Critical sections, locking, monitors, etc.
Lecture 25 More Synchronized Data and Producer/Consumer Relationship
Synchronization Lecture 23 – Fall 2017.
Producer-Consumer Problem
Multithreading.
Implementing Mutual Exclusion
Implementing Mutual Exclusion
Lecture 9 Synchronization.
CSE 153 Design of Operating Systems Winter 19
CS333 Intro to Operating Systems
CSE 451 Section 1/27/2000.
Problems with Locks Andrew Whitaker CSE451.
Software Engineering and Architecture
More concurrency issues
Presentation transcript:

How not to do Java Concurrency And how to find if you did it wrong Mark Winterrowd

Introductions Coverity Me You! Bob Copyright Coverity, Inc., 20142

Meet Bob Bob's development philosophy: Speed is everything Clever tweaks are their own reward Trying it out once or twice is plenty testing Your manager has assigned him to help you out! Copyright Coverity, Inc., 20143

Your Mission: Keep your code correct! Bob will write code mirroring mistakes seen in the wild For novices: preparation for handling your own Bob For experts: Examples occurring in real code Modeled off of code seen in Tomcat, Eclipse and Android Copyright Coverity, Inc., 20144

Patterns discussed here are low level Prefer to use higher level structures e.g., java.util.concurrent Hide uses behind higher level calls or objects Sometimes unavoidable Copyright Coverity, Inc., 20145

Multithreaded Lazy Initialization Or, sacrificing correctness for speed

Task: Lazily initialize a singleton In a single-threaded program: private static MyObj inst = null; public static MyObj getInst() { if(inst == null) { inst = new MyObj(); } return inst; } This won't work in a multithreaded program. Copyright Coverity, Inc., 20147

Simple Fix: private static MyObj inst = null; static final Object initLock = new Object(); public static MyObj getInst() { synchronized(initLock) { if(inst == null) { inst = new MyObj(); } return inst; } Bob objects: "This requires you to wait to get the lock every time!" Copyright Coverity, Inc., 20148

Bob's Performance Optimization public static MyObj getInst() { inst = new MyObj(); } return inst; } "Since we only need to set inst the first time, synchronizing to check for null is unnecessary!" Copyright Coverity, Inc., if(inst == null) { synchronized(initLock) { Is Bob right? Is his code correct?

Bob's optimized code in action Copyright Coverity, Inc., Thread 1Thread 2 if(inst == null) synchronized(initLock) inst = new MyObj(); return inst;synchronized(initLock) inst = new MyObj(); return inst; No longer a singleton!

The JVM can start and stop threads at will Holding a lock prevents another thread from executing code guarded by the same lock object Bob says "In that case, I have an idea!" Copyright Coverity, Inc.,

"Also check in the synchronized block!" private static MyObj inst = null; static final Object initLock = new Object(); public static MyObj getInst() { if(inst == null) synchronized(initLock) { Copyright Coverity, Inc., "Now, we can't have inst be initialized multiple times!" } return inst; } if(inst == null) inst = new MyObj(); Is Bob right? Is his code correct?

Let's take a look at this line Copyright Coverity, Inc., inst = new MyObj(); MyObj() { this.field1 = someVal1; this.field2 = someVal2; } A raw MyObj is created before running the constructor (raw MyObj).field1 = someVal1; (raw MyObj).field2 = someVal2; inst = (raw MyObj);

JVM re-orders code at runtime! Must have same result in current thread Cannot move code out of or through a synchronized block Reordering inside or into a synchronized is fine! Copyright Coverity, Inc., public static MyObj getInst() { if(inst == null) synchronized(initLock) { if(inst == null) { inst = new MyObj(); } return inst; } inst = (raw MyObj) inst.field1 = someVal inst.field2 = someVal2

This instruction ordering in action: Copyright Coverity, Inc., Thread 1Thread 2 if(inst == null) synchronized(initLock) inst = (raw MyObj); return inst; Returned an uninitialized MyObj! What is the name of this bad pattern? if(inst == null)

Preventing reordering bugs Hold the lock while checking the field for null public static MyObj getInst() { Copyright Coverity, Inc., synchronized(initLock) { if(inst == null) inst = new MyObj(); } return inst; } if(inst == null) Back to our original solution! "This problem seems unlikely. Is fixing it worth the slowdown?"

What slowdown? How unlikely? Uncontested lock acquisition is fast in modern JVMs In computing, unlikely can happen often In 2004, a developer opened Eclipse bug with this comment: Copyright Coverity, Inc., "I know I'm picky, but [...] getManifest has an example of what is known as "Double-Checked Locking problem [...] BundleLoader.createClassLoader has the same problem"

In the wild: Eclipse bug Copyright Coverity, Inc., Reply in 2006: "Synchronizing the places where we lazily create ClassLoader/BundleLoaderProxy objects will cause measurable slowdown. To fix this properly would require at least three additional syncs [...] I added todo comments in the code where double checks are currently being done." A month later: "We are currently having a very hard to reproduce bug when loading preference pages of our RCP application [...] I traced the problem to getBundleLoader [...] When looking at [two methods], I saw they both contained the TODO for this bug. Isn't it better to have slightly less performance instead of possible threading bugs?"

Bug as reported in Coverity Connect Copyright Coverity, Inc.,

Premature Optimization... Especially dangerous in concurrency Rare bugs may be likely in a user's workflow Slow locking may be unnecessary contention Is the lock protecting too much data? Is the lock protecting unrelated critical sections? Can some expensive operations be safely moved outside of a locked region? Copyright Coverity, Inc.,

Choosing your locks Or rather, what not to choose

Make this code thread safe static Object[] items; void update(Object newItem) { Copyright Coverity, Inc., "Synchronize on items so another thread can't change items." Object[] oldArr = items; items = new Object[items.length + 1] items[items.length - 1] = newItem; for(int i=0; i < oldArr.length; i++){ items[i] = oldArr[i]; } } synchronized(items) {

What does synchronizing on a field do? Does not block accesses from other threads to that field Acquires a lock on the field's contents Copyright Coverity, Inc., Thread 1 synchronized(items) items = new Object[...] synchronized(items) items = new Object[...] Different contents! Object[ ] oldArr = itemsitems[...] = newItem Thread 2

Don't lock on mutable fields Copyright Coverity, Inc., static Object[] items; void update(Object newItem) { synchronized( Object[] newAr = new Object[items.length+1]; newAr[newAr.length - 1] = newItem; for(int i=0; i < items.length; i++){ newArr[i] = items[i] } items = newAr; } ) { private static final Object lock = new Object(); itemslock

Tomcat bug 46990: Locking a mutable field Copyright Coverity, Inc., "Whilst there aren't any explicit bugs caused by this, it may be behind some of the harder to reproduce bugs."

Bob sends you the following code for review Copyright Coverity, Inc., class AppCtx { private static SysCtx sCtx; public synchronized SysCtx getSysCtx() { if(sCtx == null) { sCtx = new SysCtx(); } return sCtx; } " synchronized ensures this code is thread-safe!"

What does the synchronized modifier do? Copyright Coverity, Inc., class AppCtx { private static SysCtx sCtx; public synchronized SysCtx getSysCtx() { if(sCtx == null) { sCtx = new SysCtx(); } return sCtx; } } synchronized(this) {

Two AppCtx, each in their own thread Copyright Coverity, Inc., this AppCtx 1 AppCtx 2 this sCtx null unlocked synchronized(this) Static AppCtx Members AppCtx1AppCtx2 if(sCtx == null) synchronized(this) if(sCtx == null) sCtx = new SysCtx() Initialized return sCtx; sCtx = new SysCtx()return sCtx; No longer a singleton!

Guard static members with static locks Copyright Coverity, Inc., class AppCtx { private static SysCtx sCtx; public SysCtx getSysCtx() { synchronized( ) { if(sCtx == null) { sCtx = new SysCtx(); } return sCtx; } private static final Object lock=new Object(); thislock

In the wild: Android bug Copyright Coverity, Inc., Caused loss of display info, user name, and permissions

Wait and Notify and threads communicating poorly

Thread 1 consumes results from Thread 2 LinkedList jobQueue; // Called in Thread 1 void processItemFromQueue() { QueueItem item = null; synchronized(qLock) { item = jobQueue.remove(); } processItem(item); } // Called in Thread 2 void putItemInQueue(QueueItem item) { synchronized(qLock) { jobQueue.add(item); } Copyright Coverity, Inc., What if jobQueue is empty?

The wait / notify pattern lock.wait( ) : current thread stops running, releases lock, and is placed on lock 's wait set lock.notifyAll( ) : Starts up all threads in the wait set, which attempt to re-acquire lock. Call wait when your thread needs another thread to satisfy some condition Call notifyAll when your thread has satisfied a condition for another thread Copyright Coverity, Inc.,

wait and notify in action Copyright Coverity, Inc., Executing Instructionslock Locked By Unlocked Wait Set synchronized(lock)lock.wait( ) Blocked on lock synchronized(lock)lock.wait( )synchronized(lock)lock.wait( )lock.notifyAll( )release locksynchronized(lock)release lock

You see this in a review of Bob's code: void processItemFromQueue() { QueueItem item = null; // Hold the lock as briefly as possible! if(jobQueue.empty()) synchronized(qLock) { qLock.wait(); } item = jobQueue.remove(); processItem(item); } void addItemToQueue(QueueItem item) { synchronized(qLock) { jobQueue.add(item); qLock.notifyAll(); } Copyright Coverity, Inc., Is Bob's code correct?

Bob's code in action: Copyright Coverity, Inc., Executing Instructions qLock Locked By Unlocked Wait Set if(jobQueue.empty()) Consumer qLock.wait() C Blocked on qLock synchronized(qLock) ConsumerProducer synchronized(qLock) Producer jobQueue.add(item)release qLockqLock.notifyAll() No waiting threads to notify returns true Consumer is waiting while items are in the queue!

Waiting on a stale condition is a bug Another thread can change the state between the check and the wait At best, causes unnecessary delays What if future notifications were blocked on this task? Always check wait condition while holding lock Copyright Coverity, Inc., Bob comes back with a second version...

item = jobQueue.remove(); Code review round #2 void processItemFromQueue() { QueueItem item; Copyright Coverity, Inc., Bob: "Now the wait will only occur when the queue is empty!" if(jobQueue.empty()) { processItem(item); qLock.wait(); synchronized(qLock) { Is Bob right? Is his code correct? " A thread can also wake up without being notified, interrupted, or timing out, a so- called spurious wakeup." -Object.wait() documentation } } }

Bob's code in action: Copyright Coverity, Inc., Executing Instructions qLock Locked By Unlocked Wait Set if(jobQueue.empty()) Consumer qLock.wait() C Blocked on qLock synchronized(qLock) ConsumerProducer A spurious wakeup occurs! jobQueue.remove() jobQueue empty!

Check your wait condition inside a loop! Copyright Coverity, Inc., void processItemFromQueue() { QueueItem item; synchronized(qLock) { qLock.wait(); item = jobQueue.remove(); } processItem(item); } whileif (jobQueue.empty())

In the wild: Eclipse bug Copyright Coverity, Inc., Deadlock when ctrl-x was used to cut text. Diagnosed as a wait occurring and never waking up. Remains unfixed, timeout to wait was set to 30s.

The bug (in 2004 code) In code from 2005 Copyright Coverity, Inc., This bug was "fixed" with a 30 second wait timeout in 2013.

Preventing new concurrency bugs and fixing the ones you have

Don't get overly clever! Do you need a multithreaded program? Do you need lazy initialization? Initialize using static{} Is there a higher level structure to replace wait / notify ? Our example: java.util.concurrent.BlockingQueue Sometimes it's unavoidable, or hard to remove. Copyright Coverity, Inc.,

Standard methods help somewhat Education Code reviews Testing Copyright Coverity, Inc., Nondeterminism limits effectiveness Is there anything else we can do? Don’t fix pre-existing problems

Manual Inspection Responsible for finding many of our sampled fixed defects One tip we found in Bugzilla: Copyright Coverity, Inc., No guarantee anyone will notice right away Most of the fixed bugs found by inspection had been present for over 3 years. Why not have a machine inspect your code instead? is Slow "Search[ing] for the ' synchronized ' keyword goes a long way"

Static Analysis: Automatic code inspection Open source static analysis FindBugs™ finds many issues But Coverity's static analysis finds more real bugs with better explanations and a lower rate of false reports Also, we integrate with FindBugs Copyright Coverity, Inc.,

Analyze your code for free! Coverity's SCAN program provides free defect reports for open source programs. Coverity's CodeSpotter: free-to-use SaaS analysis Also a commercial enterprise solution for proprietary software Copyright Coverity, Inc.,

More about Java Concurrency Java Language Specification "Java Concurrency in Practice" by Goetz et al "Java theory and practice: Are all stateful Web applications broken?" by Goetz "Double checked locking is broken", many signers. edLocking.html edLocking.html Copyright Coverity, Inc.,

Copyright 2014 Coverity, Inc.