Sunday, July 18, 2010

Threads part 2: functions overview.

All right, in the last article I already revealed that the thread can go to sleep. It can also do much more but for the good beginning we will start with this pleasant activity that many of us adore. Just a note: all of the methods presented in this article belong to java.lang.Thread class. Ok, cutting to the chase let's have a look at the definition:
 public static void sleep(long milliseconds) throws InterruptedException

So what actually does this method? It enables us to pause a thread for at least the time specified in the argument. Why at least? Because when the thread wakes up after specified time it goes into runnable state where it has to be chosen by the scheduler to run.
Now let's emphasize two important points about the sleep method. First of all it throws an exception so always remember to put it into the try-catch block or let the exception be handled up by declaring it.
The second thing is that the sleep method is static. So we can just invoke it like this:
 try {
Thread.sleep(1000);
catch(InterruptedException ie) {}

but also it's perfectly legal to use any instance of the thread class to do it, ie:
 Thread t = new Thread();
try {
t.sleep(1000);
catch(InterruptedException ie) {}

The thing to remember here is that it doesn't really matter on which instance of the Thread class we will invoke the sleep function. Always the thread that it is invoked from will be paused.

So far so good, right? Now it's time for another method:
 public static void yeld()

Now you probably bite your nails impatiently wondering what does it do. Ok you can stop nibbling, I will tell you. It moves the thread that it is invoked from into the runnable state. Now you probably ask a question why would one do it. This method is supposed to help the other threads with the same priority to get some time of the CPU. But it's not guaranteeded at all cause the scheduler can pick the same thread to execute. But still there is a chance that another thread will be chosen so the CPU will be utilized more fairly.

The next method I will describe today is join(). As before first goes the definition:
 public final void join() throws InterruptedException

And here goes the real magic. The method join makes the thread that it is invoked from, to wait for thread that the join() was invoked on, to finish. Yeah I know. I'll explain it using a very close example to many of us. Let's imagine a thread that is responsible for drinking vodka - its run method invokes a function drinkVodka(). But we don't want to finish drinking vodka and not to have any sort of chaser. So unless we are russians or college students we would like to have another thread that will bring chaser and what's more have it before we finish the vodka. So what we can do here is to invoke a join() method in the vodka thread on the reference to the bring-chaser thread. It will make the drinking-vodka thread to wait until the bring-chaser thread is finished.

And here is a real example, more mundane:
 public class MyThreadClass implements Runnable {
static int sum = 0;
public void run() {
try {
Thread.sleep(1000);
} catch(Exception e) {}
for(int i = 0; i < 100; i++) {
sum += 1;
}
}
public static void main(String[] args) throws Exception {
MyThreadClass r = new MyThreadClass();
Thread t = new Thread(r);
t.start();
System.out.println("Started!");
t.join();
System.out.println("The result is: " + sum);
}
}

What is happening here is that we run a new thread that waits a second and then do a simple addition. This thread is run from the main thread which waits until the calculating thread is done by invoking a join() method on it! For a simple exercise you can comment this line and see how the program behaves and what it prints.

And that's it for today! I hope you have had at least great time while reading it and that you already can't wait for another article! ;)

No comments:

Post a Comment