Site hosted by Angelfire.com: Build your free website today!
scjp section 7: threads
 
  • Write code to define, instantiate and start new threads using both java.lang.Thread and java.lang.Runnable.
  • Recognise conditions that might prevent a thread from executing.
  • Write code using synchronised wait, notify and notifyAll to protect against concurrent access problems and to communicate between threads.
  • Define the interaction among threads and object locks when executing synchronised wait, notify or notifyAll.

Threads

  1. Creating a Thread
    1. If want it to execute it's own run() method:
      • MyThread extends Thread
      • write the public void run() method
      • any other thread/class can make this one eligible for running as a separate thread by calling instanceOfMyThread.start() (calling instanceOfMyThread.run() makes it's run method execute inside the current thread).
    2. If you want it to execute the run() method of another object:
      • public void MyClass implements Runnable
      • Write the public void run() method (note: run() takes no arguments).
      • Pass an instance of MyClass to a Thread object:
            MyClass myClass = new MyClass();
            Thread t = new Thread(MyClass);
            t.start();

  2. When Execution Ends
    • when run() returns
    • thread considered dead
      • can't restart - need to create a new instance of the thread
      • can call other methods/variables though

  3. Thread Priorities
    • (low)1-10(high). Default is 5, or that of creating thread.
    • Thread.MAX_PRIORITY, Thread.MIN_PRIORITY, aThread.setPriority(intPriority), aThread.setPriority()
    • execution is platform-dependent

  4. Control of Threads
  5. thread control - overview

  6. Scheduling Implementations
    • Preemptive, Round-Robin, Priority Queueing etc.
    • Platform dependant

  7. Monitors, wait(), notify() and Object Locks
    1. Monitors
    2. A monitor is any object that can block and revive threads (any object that has synchronized code is a monitor)

    3. Object Locks
      • Every object has a lock
      • When a thread tries to enter some synchronized code it puts in a request for that objects lock, then can either:
        1. acquire the lock and move to the ready state
        2. someone else has the lock so thread moves into the objects wait set, in a 'waiting for lock' state.
      • When a thread leaves synchronized code, it automatically releases the lock for that object
      • The Class Lock controls access to all synchronized static code

    4. synchronized
      • Modifier for an entire method or...
      • within a method, can synchronize a block of code
            synchronized (someObject) {
                //synchronized code
            }

        someObject is the object we wish to obtain the lock for, usually this
      • wait(), notify() and notifyAll() must be called from within synchronized code (else get a runtime exception: IllegalMonitorStateException)

    5. wait()
      • Can throw an InterruptedException (a checked exception)
      • Causes the thread calling the (non-static) method to lose the lock on the object, giving up the CPU, and moving to wait on the objects waiting pool of threads (it's wait set)
      • Good to have in a while loop, where the condition checks if it wants a thread to have the lock, so when the thead returns here, the condition is rechecked

    6. notify()
      • Arbitrarily picks a thread from the objects wait set to resume where it left off, moving it into the 'seaking lock' state
      • Better to use notifyAll() so if CPU scheduler is using priority queueing, the threads priorities may count
      • Other ways of moving from 'waiting' to 'seeking lock' state:
        1. if had moved there from a call to wait(timeInMillis) and that time had elapsed
        2. if a thread receives an .interrupt() call

    7. yield()
      • static void Thread.yield()
      • causes whatever thread is currently in the CPU to temporarily leave, giving other threads a chance