KEMBAR78
Programming with Threads in Java | PDF
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