Previous
Index

Next


Chapter 7) Threads

Objective 1, Instantiating and starting threads

Write code to define, instantiate and start new threads using both java.lang.Thread and java.lang.Runnable

What is a thread?

Threads are lightweight processes that appear to run in parallel with your main program. Unlike a process a thread shares memory and data with the rest of the program. The word thread is a contraction of "thread of execution", you might like to imagine a rope from which you have frayed the end and taken one thread. It is still part of the main rope, but it can be separated from the main and manipulated on its own. Note that a program that runs with multiple threads is different from simply starting multiple instances of the same program, because a Threaded program will have access tot he same data within the program.

An example of where threads can be useful is in printing. When you click on a print button you probably don't want the main program to stop responding until printing has finished. What would be nice is that the printing process started running "in the background" and allowed you to continue using the main portion of the program.

It would also be useful if the main program would respond if the printing thread encountered a problem. A common example used to illustrate threads is to create a GUI application that launches a bouncing ball every time a button is clicked. Because of the speed of modern processors, by switching its time between each thread it appears that each ball has exclusive use of the processor and it will bounce around as if it was the only code running on the CPU. Unlike most language threading is embedded at the heart of the Java language, much of it at the level of the ultimate ancestor class called Object. With older languages like C/C++ there is no single standard for programming Threads.

When studying for the Java Programmers exam you need to understand the concept that when a program starts a new thread, the program no longer has a single path of execution. Just because one thread A starts running before thread B, it does not mean that thread A will finish executing before thread B, and it certainly does not mean that thread B will not start before thread A. Thus you could get a question that says something like "what is the most likely output of the following code". The exact output might depend on the underlying operating system or other programs running at the time.

Just because a Threaded program generates a certain output on your machine/operating system combination there may be no guarantee it will generate the same output on a different system. The people who set the exams questions know that it is easy to make unwarranted assumptions based on how it works on the more common platforms (read Windows) and will include questions that test your knowledge of the platform depending nature of Java threading.

Make a careful not of the exact thread objectives of the exam because it expects you to know a narrow range of topics really well, but there are many Thread related topics that the exam does not cover. Thus you do not need to know about thread groups, thread pooling thread priorities and many other thread topics. Of course it might be useful to know about these topics for real world Java programming, but if you want to concentrate narrowly on the objectives just stick to the topics listed in this tutorial.

The two ways of creating a thread

Of the two methods of creating a new thread the use of Runnable is probably more common, but you must know about both for the purpose of the exam. Here is an example of a class created with the Runnable interface.

class MyClass implements Runnable{
 public void run(){//Blank Body}
}



Creating two threads of execution.

MyClass mc = new MyClass();
MyClass mc2 = new MyClass();
Thread t = new Thread(mc);
Thread t2 = new Thread(mc2);
t.start();
t2.start();

Note that that there is no guarantee that thread t will finish execution before thread t2. Of course with no code in the body of the run method it is highly likely that t will finish before t2, but no guarantee. Even if you run the code a thousand or so times on your computer and you get the same order of completion, you cannot be certain that on another operating system, or even with a different set of circumstances on your machine the order of completion will be the same.

Note that the Runnable method of creating a new thread requires an instance of the Thread class to be created, and have the Runnable class passed as a parameter to the constructor.


Any class that implements an interface must create a method to match all of the methods in the interface. The methods need not do anything sensible, i.e. they may have blank bodies, but they must be there. Thus I include the method run even in this little example, because you must include a run method if you implement Runnable. Not including a run method will cause a compile time error. 

To do anything useful when you create a thread of execution from a class you would, of course need to put something where I have put

//Blank Body.

The other method for creating a thread is to create a class that is descended from Thread. This is easy to do but it means you cannot inherit from any other class, as Java only supports single inheritance. Thus if you are creating a Button you cannot add threading via this method because a Button inherits from the AWT Button class and that uses your one shot at inheritance. There is some debate as to which way of creating a thread is more truly object oriented, but you do need to go into this for the purpose of the exam.

Instantiating and starting a Thread

Although the code that runs in your thread is in a method called run, you do not call this method directly, instead you call the start method of the thread class. This is a really important point that is likely to come up on the exam. It can easily catch you out because it runs against the grain of most Java programming you do. Normally if you put code in a method, you cause that code to execute by calling the method. There are no rules against calling the run method directly, but it will then execute as an ordinary method rather than as part of the thread.

The Runnable interface does not contain a start method, so to get at this and the other useful methods for threads (sleep, suspend etc etc), you pass your class with the Runnable interface as the constructor to an instance of the Thread class.

Thus to cause the thread to execute from a class that implements Runnable you would call the following

MyClass mc = new MyClass();
Thread t = new Thread(mc);
t.start();

Although it is the run method code that executes, a thread is actually started via the start method



Again note that was a call to start, not a call to run, even though it is the code in the run method in your class that actually executes.

If you create your class as a sub class of Thread you can simply call the start method. The drawback of sub classing the Thread class is that due to only supporting single inheritance you cannot inherit the functionality of any other class.

Questions

Question 1)

What will happen when you attempt to compile and run this code?

public class Runt implements Runnable{
public static void main(String argv[]){
        Runt r = new Runt();
        Thread t = new Thread(r);
        t.start();
        }

        public void start(){
        for(int i=0;i<100;i++)
                System.out.println(i);
        }
}

1) Compilation and output of count from 0 to 99
2) Compilation and no output
3) Compile time error: class Runt is an abstract class. It can't be instantiated.
4) Compile time error, method start cannot be called directly


Question 2)

Which of the following statements are true?

1) Directly sub classing Thread gives you access to more functionality of the Java threading capability than using the Runnable interface
2) Using the Runnable interface means you do not have to create an instance of the Thread class and can call run directly
3) Both using the Runnable interface and subclassing of Thread require calling start to begin execution of a Thread
4) The Runnable interface requires only one method to be implemented, this is called run


Question 3)

What will happen when you attempt to compile and run the following code?

public class Runt extends Thread{
public static void main(String argv[]){
        Runt r = new Runt();
        r.run();
        }
        public void run(){
        for(int i=0;i<100;i++)
                System.out.println(i);
        }
}

1) Compilation and output of count from 0 to 99
2) Compilation and no output
3) Compile time error: class Runt is an abstract class. It can't be instantiated.
4) Compile time error, method start has not been defined


Question 4)

Which of the following statements are true?

1)To implement threading in a program you must import the class java.io.Thread
2) The code that actually runs when you start a thread is placed in the run method
3) Threads may share data between one another
4) To start a Thread executing you call the start method and not the run method

Question 5)

Which of the following is valid code for starting the execution of a thread

1)

public class TStart extends Thread{
   public static void main(String argv[]){
    TStart ts = new TStart();
    ts.start();
    }
    public void run(){
    System.out.println("Thread starting");
    }
}

2)

public class TStart extends Runnable{
    public static void main(String argv[]){
    TStart ts = new TStart();
    ts.start();
    }
    public void run(){
    System.out.println("Thread starting");
    }
}

3)

public class TStart extends Thread{
    public static void main(String argv[]){
    TStart ts = new TStart();
    ts.start();
    }
    public void start(){
    System.out.println("Thread starting");
    }
}

4)

public class TStart extends Thread{
    public static void main(String argv[]){
    TStart ts = new TStart();
    ts.run();
    }
    public void run(){
    System.out.println("Thread starting");
    }
}
    
   

Answers

Answer 1)

3) Compile time error: class Runt is an abstract class. It can't be instantiated.

The class implements Runnable but does not define the run method.

Answer 2)

3) Both using the Runnable interface and subclassing of Thread require calling start to begin execution of a Thread
4) The Runnable interface requires only one method to be implemented, this is called run

Answer 3)

1) Compilation and output of count from 0 to 99

However, note that this code does not start the execution of the Thread and the run method should not be called in this way.

Answer 4)

2)The code that actually runs when you start a thread is placed in the run method
3) Threads may share data between one another
4) To start a Thread executing you call the start method and not the run method

You do not need to import any classes as Threading is an integral part of the Java language

Answer 5)

1)

Only option 1 is a valid way to start a new thread executing. The code for option 2 extends Runnable which makes no sense as Runnable is an interface not a class, an interface is used with the implements keyword. The code for option 3 calls the start method directly. If you run this code you will find the text is output but only because of the direct call to the method and not because a new Thread is running. The same is true for option 4, the run method called directly is just another method and will execute like any other.


Other sources on this topic

This topic is covered in the Sun Tutorial at
http://java.sun.com/docs/books/tutorial/essential/threads/customizing.html

http://java.sun.com/docs/books/tutorial/essential/threads/

The Java Glossary

http://mindprod.com/jglossthread.html

Jyothi Krishnan on this topic at
http://www.geocities.com/SiliconValley/Network/3693/obj_sec7.html#obj22

Thread part of of Elliot Rusty Harolds Tutorial Course
http://www.ibiblio.org/javafaq/course/week11/index.html









Previous
Index

Next