Working with Threads

This example shows how to create a thread in Java, start thread and stop thread. Every application consists of at least one thread - the main thread which is started by calling the main() method of your application. Multithreaded application allows the user to perform different tasks simultaneously, eg. browse web while downloading a file and printing a document - at the same time. Each of these processes runs in its own thread.

Let’s create a simple thread which increases the counter every second until it reaches 100. The counter is displayed in console window, so you will know when the thread is running.

public class MyThread extends Thread {

private int i = 0;

public void run() {

System.out.println("MyThread started");

try {
while (i < 100) {

System.out.println(i);
i++;
Thread.sleep(1000);

}
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("MyThread ended");

}

public void stopThread() {
i = 1000;
}

}

We’ll use this thread in main class. To start a Thread you need to call start() method which invokes the run() method inside the MyThread class. The thread is running until the run() method is finished.

In the following example the main thread ends after 3 seconds, but the MyThread thread keeps running on.

public class Main {

public static void main(String[] args) throws InterruptedException {

System.out.println("application started");

MyThread myThread = new MyThread();
myThread.start();
myThread = null; // don't!!

Thread.sleep(3000);

System.out.println("application stopped");

}

}

Setting a thread object to null, doesn’t stop the thread - you will only lose the reference to the object and you won’t be able to reach it. Don’t ever do that!

Stopping thread

A thread can be stopped in many ways. Thread class might provide some effective method to stop it. If your thread is performing some complex tasks such as communicating with another server, writing to file, printing a document etc., it is good practice that a method that stops the thread also clears all used resources.

In above example of MyThread class we implemented a stopThread() method which sets the counter value high enough that the condition that runs the while loop is not fulfilled and the thread stops executing. Well, the thread will not stop immediately, but rather when condition in while loop is checked - that is after the 1 second sleeping interval.

public class Main {

public static void main(String[] args) throws InterruptedException {

System.out.println("application started");

MyThread myThread = new MyThread();
myThread.start();

Thread.sleep(3000);

myThread.stopThread();
myThread.join();

System.out.println("application stopped");

}

}

When join() method is called on myThread object, it will temporary stop the main thread and wait until end of run() method is reached.

Another way of stopping the thread is to call the interrupt() method of the Thread class. This method throws an InteruptedException so it must be handled in a proper way. In our example of MyThread class, it is most likely that the InterruptedException is thrown while the thread is sleeping - so the exception must be caught outside the while loop, otherwise the while loop will continue running.

public class Main {

public static void main(String[] args) throws InterruptedException {

System.out.println("application started");

MyThread myThread = new MyThread();
myThread.start();

Thread.sleep(3000);

myThread.interrupt();

System.out.println("application stopped");

}

}

As you already know, Java application won’t be terminated until at least one Thread is running - even if main thread has ended. To completely terminate Java application when end of main method is reached, you need to set myThread to be running as a daemon. This means that the myThread will be stopped immediately when the thread that created myThread will end.

public class Main {

public static void main(String[] args) throws InterruptedException {

System.out.println("application started");

MyThread myThread = new MyThread();
myThread.setDaemon(true);
myThread.start();

Thread.sleep(3000);

System.out.println("application stopped");

}

}

Synchronizing threads

Thread A creates and starts Thread B. Thread A can wait until execution of Thread B has finished, and then proceed.

In the following example we’ll use a plain object sync to synchronize two threads. When Main thread starts MyThread it will call wait() method upon sync object and put the sync object into ‘waiting state’. At this point the Main thread will stop for 30 seconds. Meanwhile MyThread executes its run method and at the end calls notifyAll() method upon the sync object (that’s why it is static). Sync object is released from its waiting state and the Main thread continues. A common example of such programming is a program that can send commands to a remote device and receive a response. The whole process might take a few seconds. Meanwhile the parent thread can be stopped until the communication with the device if finished.

public class MyThread extends Thread {

private int i = 0;

public void run() {

System.out.println("start");

try {
while (i < 5) {

System.out.println(i);
i++;

Thread.sleep(1000);

}
} catch (InterruptedException e) {
e.printStackTrace();
}

synchronized (Main.sync) {
Main.sync.notifyAll();
}

System.out.println("end");

}

}

This is what the Main class should look like:

public class Main {

public static Object sync = new Object();

public static void main(String[] args) throws InterruptedException {

MyThread myThread = new MyThread();
myThread.start();

synchronized (sync) {
sync.wait(10*1000);
}

myThread.interrupt();
myThread = new MyThread();
myThread.start();


}

}