Chapter9

Un article de Sometimes Kitties Think Too.

SCJP


Sommaire

Chapter 9 - Threads


Objectives:

4.1 Defining, instantiating and starting threads

4.2 Thread States & Transitions
        Recognize the states in which a thread can exist and identify ways in which a thread can transition from one state to another

4.3 Synchronizing Code
        Given a scenario write code that makes appropriate use of object locking to protect static or instance variables from concurrent access problem

4.4 Thread Interaction
        Given a scenario, write code that makes appropriate use of wait/notify/notifyAll

Notes:

+ an instance of Thread is an object

+ a 'thread of execution' is a lightweight process

+ the JVM doesn't care about letting daemon threads complete, so when all user threads are complete the JVM can/will shutdown

+ 2 ways to create threads:

    1) extend java.lang.Thread
    2) Implement 'Runnable' interface


    Method #1:
        class Thready extends Thread {
                public void run() {
                        // must implement run()
                }
        }
       ........(instantiate)............
       Thready t = new Thready();
       t.start();


    Method #2:
        class notExtend implements Runnable {
                public void run() {
                        // must define method
                }
        }
       ........(instantiate)............
       Thread t = new Thread(new notExtend());
       t.start();
     

+ when run() is called, it becomes a 'thread of execution' and operates in a separate stack

+ run() can be overloaded, but the overloaded run()-method will not be called automatically

+ the overloaded run() method does not operate in a separate stack

+ the Runnable passed to the thread constructor is called the "target"

+ Once a thread has been started, you can never call start() again for that thread, doing so will result in IllegalThreadStateException.

+ if a thread is in the 'dead' state, calling start() on that thread will cause runtime exception.

+ Thread also implements runnable so you could do

       Thread t = new Thread( new AnotherThread());

Thread States

       new - instantiated but not started
       alive - once start has been called, even though may not be running
               Runnable
                       + eligible to run (start has been called) but
                         scheduler has not scheduled it yet
               Running
                       + scheduler chooses thread from runnable pool
               Waiting/Blocked/Sleeping
                       + Thread is not-eligible to run, but can return to runnable state
                       + in each of these states, it is returned to the runnable
                          pool after activity completes
       dead - after run completes



+ calling the run() method directly does not make a separate 'thread of execution' - it only runs on the current stack

+ target Runnable doesn't have a reference to the Thread instance that called it. Must use Thread.currentThread() method


+ once a thread has been started it cannot be restarted otherwise throws an IllegalThreadStateException

+ Methods from java.Lang.Thread

       static void sleep(long ms)
       static void yield() throws InterruptedException 
       final join() 
       final setPriority(int p)

+ void sleep() throws InterruptedException

       sleeps for # of milliseconds.
       guaranteed to make thread wait....unless interrupted


+ void yield()

       not-guaranteed, best effort to make thread wait for another similar-prioritied thread
       if there are no threads in the thread pool of a similar priority it might not back out

+ void setPriority(int)

       sets priority of thread, n is 1-10 with 10 being the highest priority
       currently running thread should have higher priority than other threads


+ methods inherited from java.lang.Object

       final void wait() throws InterruptedException
       final void notify() throws IllegalMonitorStateException 
       final void notifyAll() throws IllegalMonitorStateException 


+ sleep() and yield() are STATIC methods

+ JVM uses preemptive, priority-based scheduling

+ a thread's default priority is the priority of the thread of execution that creates it

+ wait() and sleep() throw InterruptedExceptions

+ yield() won't cause a thread to go into waiting/sleeping/blocking

+ join() - blocks the current thread from becoming runnable until the thread referenced by t is no longer alive

Synchronization

  • To protect data:
        1) mark the variable space private
        2) synchronize the code block by modifying the variables
  • to synchronize a method must acquire an object lock
       (cannot acquire a lock on a primitive!)

+ static methods can be synchronized - they lock the class literal for that class

+ they lock instance of java.lang.Class which represents the class

       e.g. MyClass.class

Blocking.......

       1) non-static synchronized methods will only block if they're invoke using the same instance
       2) static synchronized methods will ALWAYS block each other
       3) static and non-static synchronized methods will NEVER block


+ access to static fields should be done from static synchronized methods

+ non-static fields should be accessed from non-static sync'ed methods

+ wait(), notify() and notifyAll() must be called from within synchronized contexts

+ can't invoke wait/notify on an object unless it owns that objects lock

+ if thread calling wait() and it doesn't own the lock ----> IllegalMonitorStateException()

+ it's good practice to require a thread to recheck isEmpty() since a notify could have been already fired off on a method that is just entering wait()

Questions:


1) Since wait, notify and notifyAll are Object methods, can they be called from non-Thread objects?