Programming with Threads in Java koji lin@twjug 2012/9/15
java.lang.Thread
Multiple Threads with in the same program can be scheduled simultaneously on multiple CPUs. Most modern operating systems treat threads, not processes, as the basic units of scheduling ~Java concurrency in practice
On a computer with multiprocessors, processes or threads can run on different processors ~MSDN Threads and Processes
其實只想講上面兩段 ,結束(誤)
Thread Basics
Threads are everywhere ● JVM creates thread for GC ● AWT, Swing and JavaFX use event dispatch thread ● Timer for deferred tasks ● Application server handles multiple client – Servlet must be thread-safe ● RMI
What is Thread? ● Process – A program in execution – Providing the resources needed to execute a program – One process can't access or modify other process
What is Thread? ● Thread – A basic unit of CPU utilization – Lightweight process (LWP) – Multiple threads are executed within a process ● Share process's virtual address space and system resource
Thread and Process
Benefits of Thread
Multithreading Models ● User threads – Efficient, flexible – Above the kernel, without kernel support ● Kernel threads – kernel can assign one thread to each logical core in a system
Multithreading Models ● User Level Threading – Many-to-One(N:1) – Green Threads, GNU Portable Threads ● Kernel Level Threading – One-to-One(1:1) – FreeBSD, Linux, Windows, Mac, Solaris... ● Hybrid – Many-to-Many(M:N) – Solaris(before 9), Tru64 Unix
Java on each OS ● Windows – Native thread(Windows 95/NT) ● Linux – Native thread since JDK 1.3 – LinuxThread, NPTL(Since Red Hat 9) ● FreeBSD – Native thread since JDK 1.3.1 – libpthread(FreeBSD 5.3) – libthr(FreeBSD 7)
How JVM creates thread? ● Thread.java – Start0 invokes StartThread ● jvm.cc – VM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread)) invokes JavaThread ● Thread.cpp – JavaThread::JavaThread invokes os::create_thread ● os_windows.cpp, os_linux.cpp, os_bsd.cpp – Win32 Thread,NPTL, libthr
Does JVM do something special?
No!!
So, Why Thread in Java? ● Thread is inescapable feature of Java ● Take advantage of multiprocessor system ● Simplify modeling ● Thread is cheap ● Don't need to worry about memory model in different environment
Risks ● Safety Hazards – synchronization ● Liveness Hazards – deadlock – starvation ● Performance Hazards – context switch – synchronization
Thread safety ● Behaves correctly when accessed from multiple threads, and there is no synchronization or coordination on caller – java.text.SimpleDateFormat is not thread safe – Stateless servlet is safe
Race conditions ● The output is dependent on the sequence or timing of other uncontrollable events 1) if(!map.containsKey(key)){ map.put(key,value); } 2) int n; int calculate(){ return n++; }
Synchronized ● Only one thread can execute the block of code protected by the same lock at the same time ● Ensures that each thread entering a synchronized block of code sees the effects of all previous modifications that were guarded by the same lock synchronized(object) { //do something... … }
Visibility problem ● There is no guarantee that the reading thread will see a value written by another thread ● Using lock or volatile variable
Immutability ● Immutable object is always thread-safe – Its state cannot be modified after construction – All its fields are final – It is properly constructed (object doesn't escape during construction) ● Even when synchronization is not used to publish the object reference
Safe publication ● Objects that are not immutable must be safely published ● A properly constructed object can be safely published by: – Initializing an object reference form static initializer – Storing into volatile or AtomicReference – Storing into a final field of properly constructed object – Storing into a field properly guarded by lock
Java Memory Model(JSR-133) ● Defines the semantics of multithreaded programs – Ensure your program run on all processor architecture ● Happens-before – If no, JVM is free to reorder ● New guarantees for Volatile ● Initialization Safety – final
Happens-before ● Program order ● Monitor lock – explicit Lock object ● Volatile variable – AtomicXXX ● Thread start, termination ● Interruption
Happens-before ● Finalizer ● Some class libraries – Concurrent containers ● Transitivity – A -> B ,B -> C then A -> C
Volatile Map configOptions; volatile boolean initialized = false; // In Thread A configOptions = new HashMap(); ConfigOptions.put(); initialized = true; // In Thread B while (!initialized) sleep(); // use configOptions
Initialization Safety ● When object is properly constructed, then all threads will see the values for its final fields that were set in its constructor, regardless of whether or not synchronization is used ● Similar to a happens-before relationship between the write of a final field in a constructor and the initial load of a shared reference to that object in another thread
Executor framework ● If we have lots of tasks with threads, we need to consider: – How many thread should we create? – How to stop them? – What happened when a task failed?
Executor framework ● Executor manages running tasks – Submit a Runnable to be run with Executor#execute() final ExecutorService executor = ...; executor.execute(new Runnable(){ @Override public void run(){ // do the task } });
Task cancellation ● Using interruption public class Thread{ public void interrupt(){} public boolean isInterrupted(){} public static boolean interrupted(){} } ● Responding to interruption – throw exception again – set interruption status
Non-interruptible block ● Synchronous Socket IO – Close socket ● Lock – Using explicit Lock and lockInterruptibly
java.util.concurrent.* ● Atomic* ● Lock – ReentrantLock – ReadWrtieLock ● CountDownLatch ● Semaphore ● ConcurrentHashMap ● Fork/Join (Java SE 7)
Atomic* ● Lock-free thread-safe on single variable ● AtomicInteger, AtomicLong, AtomicReference , etc. – getAndAdd, addAndGet, incrementAndGet, decrementAndGet, compareAndSet, etc. ● AtomicStampedReference, AtomicMarkableReference – ABA problem
Lock interface Lock { void lock(); void unlock(); … } ● Only one thread can hold a lock at once ● ReentrantLock – Can be reacquired by same thread – Other threads can't acquire lock until has been released same number of times has been acquired
ReadWriteLock(1) ● Readers-writers problem – 同時有複數個讀與寫的動作想要執行 , 當有寫入動作 時,其他讀寫都不能執行;而沒有寫入動作時,則可 同時執行多個讀取。 ● Writer starvation/Writer preference ● Fair/Unfair mode – 是否依照抵達順序 – 實作上看似仍會去避免無限期延遲的狀況
ReadWriteLock(2) ● Fair - 當 reader 取得 lock 後有 writer 在等待, 那麼之後的 reader 將會等到該 writer 取得並釋 放後才能取得。 ● Unfair - 當 Queue 中沒有 reader 時,行為同上 ; 但是當新的 reader 到達時,還有 reader 在 deque ,則新 reader 會跳過等待的 writer 先執行。 (bug id:6816565)
Semaphore ● Counting Semaphore ● 用於管理有限資源存取 – 例如 Pool ● acquire(), tryAcquire() – 當計數不為 0 時,內部計數減1並允許執行 – 如果計數為 0 則等待直到計數不為 0 ● release() – 內部計數加1
ConcurrentHashMap ● We love HashMap – An easy to use Key-Value store ● Some new methods aware concurrency – putIfAbsent – remove(key, value) – replace(key, value) – replace(key, old value, new value)
JDK7 Fork/Join ● Fine-Grain Parallelism 1.Divide large task into small tasks 2.Process each task in separate thread 3.Join results ● ForkJoinPool ● ForkJoinTask – RecursiveTask – RecursiveAction
JDK7 Fork/Join ● Work Stealing
JDK8 ParallelIterable public interface ParallelIterable<T> ... { void forEach(Block<? super T> block)... ... } ● Based on Fork/Join ● More elegant with lambda users.parallel().forEach( u -> {...}); users.parallel().sorted( (u1, u2) -> u1.name.compareTo(u2.name));
Useful tools ● ps -eLF – show thread and process information ● jstack, jcmd – command line, useful on server environment ● Jconsole, VisualVM – visual tool integrate commands and tools
Is multithreaded programming hard ?
Yes
More... ● To utilize multiprocessor, which one is better? – Thread or Process ● Performance – How many thread is enough? Or only one thread? ● Other language or platform – Python, Ruby, C, Node.js, .Net, etc.
Reference ● WIKIPEDIA Thread – http://en.wikipedia.org/wiki/Thread_(computing) ● Extending the Haskell Foreign Function Interface with Concurrency – Simon Marlow, Simon Peyton Jones, and Wolfgang Thaller, Haskell workshop 2004. ● JSR-133 ● http://www.cs.umd.edu/~pugh/java/memoryMod el/jsr-133-faq.html#volatile
Reference ● Java Concurrency in Practice ● Performance of Multi-Process and Multi- ThreadProcessing on Multi-core SMT Processors – https://www.research.ibm.com/trl/people/inouehrs/p df/IISWC2010_inoue_slides.pdf ● Java Technology on the Linux Platform – http://java.sun.com/developer/ technicalArticles/Programming/linux/ ● http://hg.openjdk.java.net/
Reference ● Java theory and practice: Fixing the Java Memory Model, Part 2 – http://www.ibm.com/developerworks/library/j- jtp03304/ ● Programming with POSIX Threads ● Kernel Programming Guide(OS X) – https://developer.apple.com/library/mac/#document ation/Darwin/Conceptual/KernelProgramming/Mach /Mach.html

Programming with Threads in Java

  • 1.
    Programming with Threadsin Java koji lin@twjug 2012/9/15
  • 2.
  • 3.
    Multiple Threads within the same program can be scheduled simultaneously on multiple CPUs. Most modern operating systems treat threads, not processes, as the basic units of scheduling ~Java concurrency in practice
  • 4.
    On a computerwith multiprocessors, processes or threads can run on different processors ~MSDN Threads and Processes
  • 5.
  • 6.
  • 7.
    Threads are everywhere ● JVM creates thread for GC ● AWT, Swing and JavaFX use event dispatch thread ● Timer for deferred tasks ● Application server handles multiple client – Servlet must be thread-safe ● RMI
  • 8.
    What is Thread? ● Process – A program in execution – Providing the resources needed to execute a program – One process can't access or modify other process
  • 9.
    What is Thread? ● Thread – A basic unit of CPU utilization – Lightweight process (LWP) – Multiple threads are executed within a process ● Share process's virtual address space and system resource
  • 10.
  • 11.
  • 12.
    Multithreading Models ● User threads – Efficient, flexible – Above the kernel, without kernel support ● Kernel threads – kernel can assign one thread to each logical core in a system
  • 13.
    Multithreading Models ● User Level Threading – Many-to-One(N:1) – Green Threads, GNU Portable Threads ● Kernel Level Threading – One-to-One(1:1) – FreeBSD, Linux, Windows, Mac, Solaris... ● Hybrid – Many-to-Many(M:N) – Solaris(before 9), Tru64 Unix
  • 14.
    Java on eachOS ● Windows – Native thread(Windows 95/NT) ● Linux – Native thread since JDK 1.3 – LinuxThread, NPTL(Since Red Hat 9) ● FreeBSD – Native thread since JDK 1.3.1 – libpthread(FreeBSD 5.3) – libthr(FreeBSD 7)
  • 15.
    How JVM createsthread? ● Thread.java – Start0 invokes StartThread ● jvm.cc – VM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread)) invokes JavaThread ● Thread.cpp – JavaThread::JavaThread invokes os::create_thread ● os_windows.cpp, os_linux.cpp, os_bsd.cpp – Win32 Thread,NPTL, libthr
  • 16.
  • 17.
  • 18.
    So, Why Threadin Java? ● Thread is inescapable feature of Java ● Take advantage of multiprocessor system ● Simplify modeling ● Thread is cheap ● Don't need to worry about memory model in different environment
  • 19.
    Risks ● Safety Hazards – synchronization ● Liveness Hazards – deadlock – starvation ● Performance Hazards – context switch – synchronization
  • 20.
    Thread safety ● Behaves correctly when accessed from multiple threads, and there is no synchronization or coordination on caller – java.text.SimpleDateFormat is not thread safe – Stateless servlet is safe
  • 21.
    Race conditions ● The output is dependent on the sequence or timing of other uncontrollable events 1) if(!map.containsKey(key)){ map.put(key,value); } 2) int n; int calculate(){ return n++; }
  • 22.
    Synchronized ● Only one thread can execute the block of code protected by the same lock at the same time ● Ensures that each thread entering a synchronized block of code sees the effects of all previous modifications that were guarded by the same lock synchronized(object) { //do something... … }
  • 23.
    Visibility problem ● There is no guarantee that the reading thread will see a value written by another thread ● Using lock or volatile variable
  • 24.
    Immutability ● Immutable object is always thread-safe – Its state cannot be modified after construction – All its fields are final – It is properly constructed (object doesn't escape during construction) ● Even when synchronization is not used to publish the object reference
  • 25.
    Safe publication ● Objects that are not immutable must be safely published ● A properly constructed object can be safely published by: – Initializing an object reference form static initializer – Storing into volatile or AtomicReference – Storing into a final field of properly constructed object – Storing into a field properly guarded by lock
  • 26.
    Java Memory Model(JSR-133) ● Defines the semantics of multithreaded programs – Ensure your program run on all processor architecture ● Happens-before – If no, JVM is free to reorder ● New guarantees for Volatile ● Initialization Safety – final
  • 27.
    Happens-before ● Program order ● Monitor lock – explicit Lock object ● Volatile variable – AtomicXXX ● Thread start, termination ● Interruption
  • 28.
    Happens-before ● Finalizer ● Some class libraries – Concurrent containers ● Transitivity – A -> B ,B -> C then A -> C
  • 29.
    Volatile MapconfigOptions; volatile boolean initialized = false; // In Thread A configOptions = new HashMap(); ConfigOptions.put(); initialized = true; // In Thread B while (!initialized) sleep(); // use configOptions
  • 30.
    Initialization Safety ● When object is properly constructed, then all threads will see the values for its final fields that were set in its constructor, regardless of whether or not synchronization is used ● Similar to a happens-before relationship between the write of a final field in a constructor and the initial load of a shared reference to that object in another thread
  • 31.
    Executor framework ● If we have lots of tasks with threads, we need to consider: – How many thread should we create? – How to stop them? – What happened when a task failed?
  • 32.
    Executor framework ● Executor manages running tasks – Submit a Runnable to be run with Executor#execute() final ExecutorService executor = ...; executor.execute(new Runnable(){ @Override public void run(){ // do the task } });
  • 33.
    Task cancellation ● Using interruption public class Thread{ public void interrupt(){} public boolean isInterrupted(){} public static boolean interrupted(){} } ● Responding to interruption – throw exception again – set interruption status
  • 34.
    Non-interruptible block ● Synchronous Socket IO – Close socket ● Lock – Using explicit Lock and lockInterruptibly
  • 35.
    java.util.concurrent.* ● Atomic* ● Lock – ReentrantLock – ReadWrtieLock ● CountDownLatch ● Semaphore ● ConcurrentHashMap ● Fork/Join (Java SE 7)
  • 36.
    Atomic* ● Lock-free thread-safe on single variable ● AtomicInteger, AtomicLong, AtomicReference , etc. – getAndAdd, addAndGet, incrementAndGet, decrementAndGet, compareAndSet, etc. ● AtomicStampedReference, AtomicMarkableReference – ABA problem
  • 37.
    Lock interface Lock { void lock(); void unlock(); … } ● Only one thread can hold a lock at once ● ReentrantLock – Can be reacquired by same thread – Other threads can't acquire lock until has been released same number of times has been acquired
  • 38.
    ReadWriteLock(1) ● Readers-writers problem – 同時有複數個讀與寫的動作想要執行 , 當有寫入動作 時,其他讀寫都不能執行;而沒有寫入動作時,則可 同時執行多個讀取。 ● Writer starvation/Writer preference ● Fair/Unfair mode – 是否依照抵達順序 – 實作上看似仍會去避免無限期延遲的狀況
  • 39.
    ReadWriteLock(2) ● Fair - 當 reader 取得 lock 後有 writer 在等待, 那麼之後的 reader 將會等到該 writer 取得並釋 放後才能取得。 ● Unfair - 當 Queue 中沒有 reader 時,行為同上 ; 但是當新的 reader 到達時,還有 reader 在 deque ,則新 reader 會跳過等待的 writer 先執行。 (bug id:6816565)
  • 40.
    Semaphore ● Counting Semaphore ● 用於管理有限資源存取 – 例如 Pool ● acquire(), tryAcquire() – 當計數不為 0 時,內部計數減1並允許執行 – 如果計數為 0 則等待直到計數不為 0 ● release() – 內部計數加1
  • 41.
    ConcurrentHashMap ● We love HashMap – An easy to use Key-Value store ● Some new methods aware concurrency – putIfAbsent – remove(key, value) – replace(key, value) – replace(key, old value, new value)
  • 42.
    JDK7 Fork/Join ● Fine-Grain Parallelism 1.Divide large task into small tasks 2.Process each task in separate thread 3.Join results ● ForkJoinPool ● ForkJoinTask – RecursiveTask – RecursiveAction
  • 43.
    JDK7 Fork/Join ● Work Stealing
  • 44.
    JDK8 ParallelIterable public interface ParallelIterable<T> ... { void forEach(Block<? super T> block)... ... } ● Based on Fork/Join ● More elegant with lambda users.parallel().forEach( u -> {...}); users.parallel().sorted( (u1, u2) -> u1.name.compareTo(u2.name));
  • 45.
    Useful tools ● ps -eLF – show thread and process information ● jstack, jcmd – command line, useful on server environment ● Jconsole, VisualVM – visual tool integrate commands and tools
  • 46.
  • 47.
  • 48.
    More... ● To utilize multiprocessor, which one is better? – Thread or Process ● Performance – How many thread is enough? Or only one thread? ● Other language or platform – Python, Ruby, C, Node.js, .Net, etc.
  • 49.
    Reference ● WIKIPEDIA Thread – http://en.wikipedia.org/wiki/Thread_(computing) ● Extending the Haskell Foreign Function Interface with Concurrency – Simon Marlow, Simon Peyton Jones, and Wolfgang Thaller, Haskell workshop 2004. ● JSR-133 ● http://www.cs.umd.edu/~pugh/java/memoryMod el/jsr-133-faq.html#volatile
  • 50.
    Reference ● Java Concurrency in Practice ● Performance of Multi-Process and Multi- ThreadProcessing on Multi-core SMT Processors – https://www.research.ibm.com/trl/people/inouehrs/p df/IISWC2010_inoue_slides.pdf ● Java Technology on the Linux Platform – http://java.sun.com/developer/ technicalArticles/Programming/linux/ ● http://hg.openjdk.java.net/
  • 51.
    Reference ● Java theory and practice: Fixing the Java Memory Model, Part 2 – http://www.ibm.com/developerworks/library/j- jtp03304/ ● Programming with POSIX Threads ● Kernel Programming Guide(OS X) – https://developer.apple.com/library/mac/#document ation/Darwin/Conceptual/KernelProgramming/Mach /Mach.html