Two primary approaches exist for creating new execution threads in Java:
- Extending the Thread class:
- Define a sucblass of Thread and override its
run()method. - Instantiate the subclass and envoke
start()to initiate thread execution.
- Define a sucblass of Thread and override its
public class CustomThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
public class Main {
public static void main(String[] args) {
CustomThread thread = new CustomThread();
thread.start();
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
Alternatively, use an anonymous inner class:
public class Main {
public static void main(String[] args) {
Thread thread = new Thread() {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
};
thread.start();
}
}
- Implementing the Runnable interface:
- Create a class implementing Runnable and define the
run()method. - Pass an instance of this class to a Thread constructor and call
start().
- Create a class implementing Runnable and define the
public class TaskRunner implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
public class Main {
public static void main(String[] args) {
TaskRunner task = new TaskRunner();
Thread thread = new Thread(task);
thread.start();
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
Anonymous enner class implementation:
public class Main {
public static void main(String[] args) {
Runnable task = new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
};
Thread thread = new Thread(task);
thread.start();
}
}
Thread pools address thread lifecycle overhead and resource constraints. ExecutorService manages pools for Runnable and Callable tasks.
Callable example:
public class ComputationTask implements Callable<Long> {
private final int target;
public ComputationTask(int target) {
this.target = target;
}
@Override
public Long call() {
long result = 1;
for (int i = 1; i <= target; i++) {
result *= i;
}
return result;
}
}
public class Main {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService pool = Executors.newFixedThreadPool(2);
Future<Long> factorial10 = pool.submit(new ComputationTask(10));
Future<Long> factorial20 = pool.submit(new ComputationTask(20));
System.out.println("10! = " + factorial10.get());
System.out.println("20! = " + factorial20.get());
pool.shutdown();
}
}