Three Ways to Create Threads in Java: Extending Thread, Implementing Runnable, and Implementing Callable
This article explains three Java thread‑creation techniques—extending the Thread class, implementing the Runnable interface, and implementing the Callable interface—provides complete code examples for each, compares their advantages and disadvantages, and recommends the best practice for concurrent programming.
Java provides three primary ways to create a new thread: extending the Thread class, implementing the Runnable interface, and implementing the Callable interface (available since JDK 1.5). Each method has its own syntax, usage pattern, and trade‑offs.
1. Extending Thread class
//继承Thread
public class ExtendThread extends Thread {
//线程执行体
@Override
public void run() {
//do something
System.out.println("继承Thread创建线程");
//无返回值
}
}
public class ThreadCreateDemo {
public static void main(String[] args) {
//创建一个线程
ExtendThread extendThread = new ExtendThread();
//调用start方法启动线程
extendThread.start();
//没有返回值
}
}Output: 继承Thread创建线程
Note: Threads created this way cannot share instance variables because each thread has its own object, and the class cannot extend any other class due to Java’s single‑inheritance limitation.
2. Implementing Runnable interface
//实现Runnable接口
public class ImplRunnable implements Runnable {
//线程实行体
@Override
public void run() {
//do something
System.out.println("实现Runnable创建线程");
//没有返回值
}
}
public class ThreadCreateDemo {
public static void main(String[] args) {
ImplRunnable implRunnable = new ImplRunnable();
Thread thread = new Thread(implRunnable);
//启动线程
thread.start();
}
}Output: 实现Runnable创建线程
Note: The Runnable object serves only as the target for a Thread instance; the actual thread object is still a Thread , which executes the run() method of the target.
3. Implementing Callable interface
//实现Callable返回值类型为Integer类型
public class ImplCallable implements Callable
{
//该call()方法将作为线程执行体,并且有返回值
@Override
public Integer call() throws Exception {
//do something
System.out.println("实现Callable接口创建线程,返回类型为Integer类型");
return 999;
}
}
public class ThreadCreateDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable
callable = new ImplCallable();
FutureTask
futureTask = new FutureTask<>(callable);
Thread thread = new Thread(futureTask);
thread.start();
//获取返回值futureTask.get()
System.out.println(futureTask.get());
}
}Output: 999
Note: Callable is generic; its type parameter must match the return type of call() . Because it is a functional interface, it can also be created with a lambda expression.
Comparison of the three approaches
All three can achieve multithreading, but the Runnable/Callable style is generally preferred because it allows the thread class to extend other classes and enables multiple threads to share the same target object, promoting better object‑oriented design. Extending Thread is simpler and lets you access the current thread via this , but it prevents inheritance from any other class.
Recommendation
For most Java concurrency scenarios, it is advisable to implement Runnable or Callable rather than extending Thread , as this provides greater flexibility and clearer separation between task logic and thread management.
Full-Stack Internet Architecture
Introducing full-stack Internet architecture technologies centered on Java
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.