Getting started with Java Threads – Part 1
I am learning for the Java OCP 7 and summarizing some relevant infos about Multithreading.
For now I am referring to chapter 13 in the book by G.Ganesh.
You can create threads in 2 ways: extending the Thread class or implementing the Runnable interface
Extending the Thread class is more convenient if you don´t need to extend another class that is not “Thread” (since in java you can only extend one class), because you can use the class methods directly (like “getName()“).
If you implement the Runnable interface (preferred way because of inheritance) you will have to use the static method “currentThread()” of the Thread class to do your operations on the thread (like setting or getting the name).
The two fundamental methods to know are:
– run(): like a main method, necessary to enable the execution of a thread.
– start(): that creates the thread.
The thread will be terminated when the run method execution is complete. It´s invoked implicitly by the JVM (DON´T invoke it explicitly!).
The main method starts a Thread called “main“. If you create and start your own thread it will have default names like “Thread-0“, “Thread-1“.
If you extend the thread class you need to override the run() method (otherwise it does nothing). If you implement the Runnable interface you will have to implement the run() method (mandatory)
The following code will help you to understand more about these first concepts.
public class MyThread1 extends Thread { public void run() { System.out.println("Extending the Thread class - Thread name: " + getName() + " - priority: " + getPriority() + " - group: " + getThreadGroup().getName()); } }
public class MyThread2 implements Runnable { public void run() { Thread thread= Thread.currentThread(); System.out.println("Implementing the runnable interface" + " - Thread name: " + thread.getName() + " - priority: " + thread.getPriority() + " - group: " + thread.getThreadGroup().getName()); } }
public class ThreadsDemo { public static void main(String[] args) { // extending Thread Thread myThread1 = new MyThread1(); // implementing Runnable Thread myThread2 = new Thread(new MyThread2()); System.out.println("Threads defined. Default properties: "); //name, priority, group returned by the toString method System.out.println(myThread1); System.out.println(myThread2); System.out.println("Changing default names..."); myThread1.setName("Thread_1"); myThread2.setName("Thread_2"); System.out.println("Threads will be started..."); myThread1.start(); myThread2.start(); } }
The output of the main method should be something like:
Threads defined. Default properties:
Thread[Thread-0,5,main]
Thread[Thread-1,5,main]
Threads will be started...
Extending the Thread class - Thread name: Thread-0 - priority: 5 - group: main
Implementing the runnable interface - Thread name: Thread-1 - priority: 5 - group: main
Launching the main program you see that the threads are started asynchronously. Sometimes you see:
Implementing the runnable interface - Thread name: Thread-1
Extending the Thread class - Thread name: Thread-0
Sometimes it´s:
Extending the Thread class - Thread name: Thread-0
Implementing the runnable interface - Thread name: Thread-1
You can quickly proof it in Eclipse launching the program with the shortcut Ctlr+11.
To change this “random” behaviour you can set the priority with the setPriority() method, from 1, the lowest, to 10, the highest. The default is 5. They can be all retrieved by the static members:
– Thread.NORM_PRIORITY ;
– Thread.MAX_PRIORITY ;
– Thread.MIN_PRIORITY .
Threads can be in one of the following states:
– NEW (created)
– RUNNABLE (started)
– TERMINATED
– BLOCKED (waiting to acquire the lock)
– WAITING (waiting for notifications)
– TIMED_WAITING (sleep() invoked and the thread is sleeping or if wait() with timeout)
States are defined with the Thread.State enumeration.
You can get the state with the getState() method.