Creating and Managing Threads
Creating a Thread by Implementing Runnable
Create a class that implements the
Runnable
interface.Override the
run()
method with the code that should execute in the new thread.Create a
Thread
object by passing an instance of your class to theThread
constructor.Start the thread using
start()
.
class MyThread implements Runnable {
String threadName;
MyThread(String name) {
threadName = name;
}
public void run() {
System.out.println(threadName + " Starting.");
try {
for (int count = 0; count < 10; count++) {
Thread.sleep(400);
System.out.println("In " + threadName + ", count is " + count);
}
} catch (InterruptedException exc) {
System.out.println(threadName + " interrupted.");
}
System.out.println(threadName + " terminating.");
}
}
class UseThreads {
public static void main(String[] args) {
System.out.println("Main thread starting.");
MyThread mt = new MyThread("Child #1");
Thread newThrd = new Thread(mt);
// Associate thread with MyThread
newThrd.start();
// Start the thread
for (int i = 0; i < 50; i++) {
System.out.print(".");
try {
Thread.sleep(100);
} catch (InterruptedException exc) {
System.out.println("Main thread interrupted.");
}
}
System.out.println("Main thread ending.");
}
}
After calling start()
, execution returns to main()
, and it enters main()’
s for loop. Both threads continue running, sharing the CPU in single-CPU systems, until their loops finish.
Java provides much better ways of waiting for a thread to end.
A program continues to run until all of its threads have ended.
In a multi-threaded program, the main thread should be the last thread to finish running. Thus, having the main thread finish last is not a requirement. It is, however, often a good practice to follow.
2. Thread with Factory Method (Cleaner Structure)
Store the
Thread
object as an instance variable (thrd
).Provide a static factory method
createAndStart()
to create and start the thread.
class MyThread implements Runnable {
Thread thrd;
MyThread(String name) {
thrd = new Thread(this, name);
}
public static MyThread createAndStart(String name) {
MyThread myThrd = new MyThread(name);
myThrd.thrd.start(); // Start the thread
return myThrd;
}
public void run() {
System.out.println(thrd.getName() + " starting.");
try {
for (int count = 0; count < 10; count++) {
Thread.sleep(400);
System.out.println("In " + thrd.getName() + ", count is " + count);
}
} catch (InterruptedException exc) {
System.out.println(thrd.getName() + " interrupted.");
}
System.out.println(thrd.getName() + " terminating.");
}
}
class ThreadVariations {
public static void main(String[] args) {
System.out.println("Main thread starting.");
MyThread mt = MyThread.createAndStart("Child #1");
for (int i = 0; i < 50; i++) {
System.out.print(".");
try {
Thread.sleep(100);
} catch (InterruptedException exc) {
System.out.println("Main thread interrupted.");
}
}
System.out.println("Main thread ending.");
}
}
3. Creating a Thread by Extending Thread
Create a class that extends
Thread
.Override the
run()
method.Start the thread using
start()
.
class MyThread extends Thread {
MyThread(String name) {
super(name); // Set thread name
}
public void run() {
System.out.println(getName() + " starting.");
try {
for (int count = 0; count < 10; count++) {
Thread.sleep(400);
System.out.println("In " + getName() + ", count is " + count);
}
} catch (InterruptedException exc) {
System.out.println(getName() + " interrupted.");
}
System.out.println(getName() + " terminating.");
}
}
class ExtendedThread {
public static void main(String[] args) {
System.out.println("Main thread starting.");
MyThread mt = new MyThread("Child #1");
mt.start(); // Start the thread
for (int i = 0; i < 50; i++) {
System.out.print(".");
try {
Thread.sleep(100);
} catch (InterruptedException exc) {
System.out.println("Main thread interrupted.");
}
}
System.out.println("Main thread ending.");
}
}
4. Creating Multiple Threads
Multiple threads can be started using the same approach as used for a single thread. Each thread will run independently, sharing CPU time.
Running several threads concurrently by creating multiple MyThread
instances.
class MyThread implements Runnable {
Thread thrd;
MyThread(String name) {
thrd = new Thread(this, name);
}
public static MyThread createAndStart(String name) {
MyThread myThrd = new MyThread(name);
myThrd.thrd.start();
return myThrd;
}
public void run() {
System.out.println(thrd.getName() + " starting.");
try {
for (int count = 0; count < 10; count++) {
Thread.sleep(400);
System.out.println("In " + thrd.getName() + ", count is " + count);
}
} catch (InterruptedException exc) {
System.out.println(thrd.getName() + " interrupted.");
}
System.out.println(thrd.getName() + " terminating.");
}
}
class MoreThreads {
public static void main(String[] args) {
System.out.println("Main thread starting.");
MyThread mt1 = MyThread.createAndStart("Child #1");
MyThread mt2 = MyThread.createAndStart("Child #2");
MyThread mt3 = MyThread.createAndStart("Child #3");
for (int i = 0; i < 50; i++) {
System.out.print(".");
try {
Thread.sleep(100);
} catch (InterruptedException exc) {
System.out.println("Main thread interrupted.");
}
}
System.out.println("Main thread ending.");
}
}
Best Practices and Notes
Threads share CPU time and run concurrently, not necessarily in order.
Thread.sleep(milliseconds)
pauses the thread; always wrap it in atry-catch
block.A program continues to run until all non-daemon threads finish, including the main thread.
You may want to ensure the main thread finishes last for demonstration purposes, but it's not required.
Use
join()
if you need the main thread to wait for others to finish.