Previous |
Next |
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 to the 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. Threads are very commonly used to keep an interface responsive whilst ensuring that other activities can continue in the background.
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. Although threading is built into the very heart of Java, thread programming might well be described as “a bit weird”, it seems to break many of the rules and expectations of other programming, particularly because parts of your program will be running in parallel rather than in “one after the other” sequence. If you find programming threads in Java a bit tricky, you can console yourself that thread programming in any language is a challenge, and possibly less so in Java.
You need to be careful when designing threaded code because the exact path and timing when the code runs may not be predictable. Just because Thread A starts before Thread B is no guarantee that thread A will finish first. Even if thread A finishes first when you run the program 100 times there is no guarantee that it will finish first when you run it for the 101st time.
Note that subheading was platform dependence, not independence. Java Threading does not guarantee the same behaviour on different operating system. This is a subtle issue because you may well always run you Java code on the same operating system (e.g. Windows), or even two operating systems that treat threading in a similar way.
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. Not only that but some threading code can be “indeterminate”, i.e. The exact output cannot be certain.
Of the two methods of creating a new thread the use of Runnable is probably more common Here is an example of a class created with the Runnable interface.
class MyClass implements Runnable{
public void run(){/*your code goes here */}
}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. This was the object mc and mc2 in the previous example code.
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
/* your code goes here */.
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.
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 as it can mislead you because it runs against the grain of most Java programming . 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.
Other sources
Threading according to the Sun tutorial
http://java.sun.com/docs/books/tutorial/essential/concurrency/procthread.html
Previous |
Next |