Java creation threads (Runnable interface and Thread class)
In most cases, a thread is created by instantiating a Thread object. Java defines two ways:
The following describes each method in turn.
Implementing the Runnable interface
The easiest way to create a thread is to create a class that implements the Runnable interface. Runnable abstracts a code execution unit. You can create threads for each object by implementing the Runnable interface. To implement the Runnable interface, a class only needs to implement a simple method of run(), which is declared as follows:
public void run( )
In run(), you can define code to build new threads. It is crucial to understand the following: the run() method can call other methods, refer to other classes, and declare variables like the main thread. The only difference is that run() establishes another concurrent thread execution entry in the program. When run() returns, the thread ends.
After you have created a class that implements the Runnable interface, you need to instantiate an object of the Thread class inside the class. The Thread class defines several constructors. What we will use is as follows:
Thread(Runnable threadOb, String threadName)
In this constructor, threadOb is an instance that implements the Runnable interface class. This defines the starting point for thread execution. The name of the new thread is defined by threadName.
After a new thread is created, it does not run until its start() method is called, which is defined in the Thread class. Essentially, start() executes a call to run(). The Start() method is declared as follows:
void start( )
The following example is to create a new thread and start it running:
// Create a second thread.class NewThread implements Runnable { Thread t; NewThread() { // Create a new, second thread t = new Thread(this, "Demo Thread"); Syste m.out.println("Child thread: " + t); t.start(); // Start the thread } // This is the entry point for the second thread. public void run() { try { for(int i = 5; i > 0; i- -) { System.out.println("Child Thread: " + i); Thread.sleep(500); } } catch (InterruptedException e) { System.out.println("Child interrupted.") ; } System.out .println("Exiting child thread."); }}class ThreadDemo { public static void main(String args[]) { new NewThread(); // create a new thread try { for(int i = 5; i > 0 ; i--) { System.out.println("Main Thread: " + i); Thread.sleep(1000); } } catch (InterruptedException e) { System.out.println("Main thread interrupt ed."); } System.out.println("Main thread exiting."); }}
In the NewThread constructor, the new Thread object is created by the following statement:
t = new Thread(this, "Demo Thread");
This indicates that in this object you want the new thread to call the run() method. Then, start() is called, and the execution of the thread is started with the run() method. This causes the child thread for loop to start execution. After calling start(), the NewThread constructor returns to main(). When the main thread is restored, it reaches the for loop. The two threads continue to run, sharing the CPU until their loop ends. The output of this program is as follows:
Child thread: Thread[Demo Thread,5,main]Main Thread: 5Child Thread: 5Child Thread: 4Main Thread: 4Child Thread: 3Child Thread: 2Main Thread: 3Child Thread: 1E xiting child thread.Main Thread: 2Main Thread: 1Main thread exiting.
As mentioned earlier, in a multi-threaded program, the main thread must usually be the last thread that ends running. In fact, for some old JVMs, if the main thread ends before the child thread, the Java runtime system may "hang". The aforementioned program ensures that the main thread ends in the end, because the main thread sleeps for 1000 milliseconds, while the child thread is only 500 milliseconds. This causes the child thread to end before the main thread ends. In short, you will see a better way to wait for the thread to end.
Extended Thread
Another way to create a thread is to create a new class that extends the Thread class, and then creates an instance of that class. When a class inherits Thread, it must overload the run() method, which is the entry to the new thread. It also has to call the start() method to start the new thread execution. The following is to rewrite the previous program with the extended thread class:
// Create a second thread by extending Threadclass NewThread extends Thread { NewThread() { // Create a new, second thread super("Demo Thread"); System.out.printl n("Child thread: " + this); start( ); // Start the thread } // This is the entry point for the second thread. public void run() { try { for(int i = 5; i > 0; i--) { System.out.println( "Child Thread: " + i); Thread.sleep(500); } } catch (InterruptedException e) { System.out.println("Child interrupted."); } System.out.println(" Exiting child thread." ); }}class ExtendThread { public static void main(String args[]) { new NewThread(); // create a new thread try { for(int i = 5; i > 0; i--) { System.out : : : : : : : : : : : : : : : .println("Main Thread: " + i); Thread.sleep(1000); } } catch (InterruptedException e) { System.out.println("Main thread interrupted."); } System.ou t.println("Main thread exiting."); }}
This program generates the same output as the previous version. The child thread is generated by the instantiated NewThread object, which is derived from the Thread class. Note the call to super() in NewThread. This method calls the Thread constructor of the following form:
public Thread(String threadName)
Here, threadName specifies the thread name.
Choose the right method
At this point, you will definitely wonder why Java has two ways to create child threads, which one is better. All the questions are attributed to one point. The Thread class defines a variety of methods that can be overloaded by derived classes. For all methods, the only thing that must be overloaded is the run() method. This is of course the same method required to implement the Runnable interface. Many Java programmers believe that classes should be extended only when they are strengthened or modified. Therefore, if you do not overload other methods of Thread, it is best to implement only the Runnable interface. Of course it's up to you to decide. However, in other parts of this chapter, we apply classes that implement the runnable interface to create threads.