Showing posts with label running. Show all posts
Showing posts with label running. Show all posts

Saturday, February 26, 2011

Quick Review: Chapters 55 to 61 (Threads)

This is going to be the last quick recap chapter in this SCJP Series. This will cover the important points about Threads.

Defining, Instantiating, and Starting Threads

* Threads can be created by extending Thread and overriding the public void run() method.

* Thread objects can also be created by calling the Thread constructor that takes a Runnable argument. The Runnable object is said to be the target of the thread.

* You can call start() on a Thread object only once. If start() is called more than once on a Thread object, it will throw a RuntimeException.

* It is legal to create many Thread objects using the same Runnable object as the target.

* When a Thread object is created, it does not become a thread of execution until its start() method is invoked. When a Thread object exists but hasn’t been started, it is in the new state and is not considered alive.

Transitioning Between Thread States

* Once a new thread is started, it will always enter the runnable state.

* The thread scheduler can move a thread back and forth between the runnable state and the running state.

* For a typical single-processor machine, only one thread can be running at a time, although many threads may be in the runnable state.

* There is no guarantee that the order in which threads were started determines the order in which they’ll run.

* There’s no guarantee that threads will take turns in any fair way. It’s up to the thread scheduler, as determined by the particular virtual machine implementation. If you want a guarantee that your threads will take turns regardless of the underlying JVM, you can use the sleep() method. This prevents one thread from hogging the running process while another thread starves.

* A running thread may enter a blocked/waiting state by a wait(), sleep(), or join() call.

* A running thread may enter a blocked/waiting state because it can’t acquire the lock for a synchronized block of code.

* When the sleep or wait is over, or an object’s lock becomes available, the thread can only reenter the runnable state. It will go directly from waiting to running (well, for all practical purposes anyway).

* A dead thread cannot be started again.

Sleep, Yield, and Join

* Sleeping is used to delay execution for a period of time, and no locks are released when a thread goes to sleep.

* A sleeping thread is guaranteed to sleep for at least the time specified in the argument to the sleep() method (unless it’s interrupted), but there is no guarantee as to when the newly awakened thread will actually return to running.

* The sleep() method is a static method that sleeps the currently executing thread’s state. One thread cannot tell another thread to sleep.

* The setPriority() method is used on Thread objects to give threads a priority of between 1 (low) and 10 (high), although priorities are not guaranteed, and not all JVMs recognize 10 distinct priority levels—some levels may be treated as effectively equal.

* If not explicitly set, a thread’s priority will have the same priority as the priority of the thread that created it.

* The yield() method may cause a running thread to back out if there are runnable threads of the same priority. There is no guarantee that this will happen, and there is no guarantee that when the thread backs out there will be a different thread selected to run. A thread might yield and then immediately reenter the running state.

* The closest thing to a guarantee is that at any given time, when a thread is running it will usually not have a lower priority than any thread in the runnable state. If a low-priority thread is running when a high-priority thread enters runnable, the JVM will usually preempt the running low-priority thread and put the high-priority thread in.

* When one thread calls the join() method of another thread, the currently running thread will wait until the thread it joins with has completed. Think of the join() method as saying, “Hey thread, I want to join on to your end. Let me know when you’re done, so I can enter the runnable state.”

Synchronization

* synchronized methods prevent more than one thread from accessing an object’s critical method code simultaneously.

* You can use the synchronized keyword as a method modifier, or to start a synchronized block of code.

* To synchronize a block of code, you must specify an argument that is the object whose lock you want to synchronize on.

* While only one thread can be accessing synchronized code of a particular instance, multiple threads can still access the same object’s unsynchronized code.

* When a thread goes to sleep, its locks will be unavailable to other threads.

* static methods can be synchronized, using the lock from the java.lang.Class instance representing that class.

Thread Communication

* The wait() method lets a thread say, “I got nothing to do, so put me in your waiting pool and notify me when something happens that I care about.”

* The notify() method is used to send a signal to one and only one of the threads that are waiting in that same object’s waiting pool.

* The notify() method can NOT specify which waiting thread to notify.

* The method notifyAll() works in the same way as notify(), only it sends the signal to all of the threads waiting on the object.

* All three methods—wait(), notify(), and notifyAll()—must be called from within a synchronized context! A thread invokes wait() or notify() on a particular object, and the thread must currently hold the lock on that object.

Deadlocks

* Deadlocking is when thread execution grinds to a halt because the code is waiting for locks to be removed from objects.

* Deadlocking can occur when a locked object attempts to access another locked object that is trying to access the first locked object. In other words, both threads are waiting for each other’s locks to be released; therefore, the locks will never be released!


Previous Chapter: Chapter 61 - Thread Interaction

Next Chapter: Self Test - Chapters 55 to 61

Friday, February 25, 2011

Chapter 57: Thread States and Transitions

In the previous chapter we saw what a thread is and how to create them and run them too. During the chapter we used the term thread state here and there. It might have made some sense to you but not much for that matter if you are new to java programming. Well, here we are. This whole chapter is dedicated to clarify more on the thread states.

So, lets get started!!!

Thread States

We’ve already seen three thread states - new, runnable, and dead. But wait! There’s more! The thread scheduler’s job is to move threads in and out of the running state. While the thread scheduler can move a thread from the running state back to runnable, other factors can cause a thread to move out of running, but not back to runnable. One of these is when the thread’s run() method completes, in which case the thread moves from the running state directly to the dead state. Next we’ll look at some of the other ways in which a thread can leave the running state, and where the thread goes.

Thread States

A thread can be only in one of five states
New - This is the state the thread is in after the Thread instance has been created, but the start() method has not been invoked on the thread. It is a live Thread object, but not yet a thread of execution. At this point, the thread is considered not alive.
Runnable - This is the state a thread is in when it’s eligible to run, but the scheduler has not selected it to be the running thread. A thread first enters the runnable state when the start() method is invoked, but a thread can also return to the runnable state after either running or coming back from a blocked, waiting, or sleeping state. When the thread is in the runnable state, it is considered alive.
Running - This is where all the action is. This is the state a thread is in when the thread scheduler selects it (from the runnable pool) to be the currently executing process. A thread can transition out of a running state for several reasons, including because “the thread scheduler felt like it.” We’ll look at those other reasons shortly. There are several ways to get to the runnable state, but only one way to get to the running state: the scheduler chooses a thread from the runnable pool.
Waiting/blocked/sleeping - This is the state a thread is in when it’s not eligible to run. Okay, so this is really three states combined into one, but they all have one thing in common: the thread is still alive, but is currently not eligible to run. In other words, it is not runnable, but it might return to a runnable state later if a particular event occurs. A thread may be blocked waiting for a resource (like I/O or an object’s lock), in which case the event that sends it back to runnable is the availability of the resource—for example, if data comes in through the input stream the thread code is reading from, or if the object’s lock suddenly becomes available. A thread may be sleeping because the thread’s run code tells it to sleep for some period of time, in which case the event that sends it back to runnable is that it wakes up because its sleep time has expired. Or the thread may be waiting, because the thread’s run code causes it to wait, in which case the event that sends it back to runnable is that another thread sends a notification that it may no longer be necessary for the thread to wait. The important point is that one thread does not tell another thread to block. Some methods may look like they tell another thread to block, but they don’t. If you have a reference t to another thread, you can write something like this:

t.sleep() or t.yield()

But those are actually static methods of the Thread class—they don’t affect the instance t; instead they are defined to always affect the thread that’s currently executing. There is also a stop() method, but it too has been deprecated and we won’t even go there. Both suspend() and stop() turned out to be very dangerous, so you shouldn’t use them and again, because they’re deprecated, they won’t appear on the exam. Don’t study them, most importantly don’t use them. Note also that a thread in a blocked state is still considered to be alive.
Dead - A thread is considered dead when its run() method completes. It may still be a viable Thread object, but it is no longer a separate thread of execution. Once a thread is dead, it can never be brought back to life! (The whole “I see dead threads” thing.) If you invoke start() on a dead Thread instance, you’ll get a runtime (not compiler) exception. And it probably doesn’t take a rocket scientist to tell you that if a thread is dead, it is no longer considered to be alive.

Thread states & Transitions


Previous Chapter: Chapter 56 - Threads & Multithreading

Next Chapter: Chapter 57 - Preventing Thread Execution
© 2013 by www.inheritingjava.blogspot.com. All rights reserved. No part of this blog or its contents may be reproduced or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without prior written permission of the Author.

ShareThis

Google+ Followers

Followers