创建线程的几种方式?
- 继承 Thread 类创建线程;
- 实现 Runnable 接口创建线程;
- 通过 Callable 和 Future 创建线程;
- 通过线程池创建线程。
评论
- 其实创建线程就只有两种方式,一种就是直接通过继承Thread类然后实现里面的run()方法来实现,还有一种就是通过实现Runnable接口,然后把这个实现类传进Thread构造函数里面。这个通过Callable来实现的方法是因为FutureTask实现了Runnable接口,FutureTask可以接收一个Collable参数,然后把这个FutureTask传 进Thread里面,FutureTask调用run方法的时候,run方法会调用Callable的call方法然后把call方法的返回值赋给outcome属性。
我的学习
- 继承
Thread类
class MyThread extends Thread {
public void run() {
System.out.println("通过继承Thread类的方式创建线程");
}
}
public class ThreadExample {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
- 实现
Runnable接口
class MyRunnable implements Runnable {
public void run() {
System.out.println("通过实现Runnable接口的方式创建线程");
}
}
public class RunnableExample {
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
}
- 使用
Callable和Future
import java.util.concurrent.*;
class MyCallable implements Callable<Integer> {
public Integer call() throws Exception {
// 执行任务,返回结果
return 123;
}
}
public class CallableExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable<Integer> callable = new MyCallable();
FutureTask<Integer> futureTask = new FutureTask<>(callable);
Thread thread = new Thread(futureTask);
thread.start();
// 等待任务执行完毕,并获取其结果
Integer result = futureTask.get();
System.out.println("通过Callable和FutureTask方式创建的线程,结果为:" + result);
}
}
- 使用
ExceutotService
import java.util.concurrent.*;
public class ExecutorServiceExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(new Runnable() {
public void run() {
System.out.println("通过ExecutorService方式创建的线程");
}
});
executor.shutdown(); // 关闭ExecutorService,不再接受新任务
}
}
为什么需要线程池呢?
- 线程复用
- 控制最大并发数
- 管理线程的生命周期
Executors
创建一个线程池,重复使用固定数量的线程,这些线程在共享的无界队列上运行。 在任何时候,最多会有nThreads个线程在处理任务。如果在所有线程都处于活动 状态时提交了其他任务,它们将在队列中等待,直到有线程可用。如果任何线程在 关闭前的执行过程中因故障而终止,则会有新的线程代替它执行后续任务。线程池 中的线程将一直存在,直到明确关闭为止。
Executors.newFixedThreadPool(int nThreads)
创建一个线程池,根据需要创建新线程,但在有可用线程时会重复使用以前构建的 线程。这些线程池通常能提高执行大量短期异步任务的程序的性能。如果有可用线 程,执行调用将重用以前构建的线程。如果没有可用的线程,则会创建一个新线程 并添加到线程池中。六十秒内未使用的线程将被终止并从缓存中删除。因此,闲置 足够长时间的线程池不会消耗任何资源。请注意,可以使用ThreadPoolExecutor 构造函数创建具有类似属性但细节(例如超时参数)不同的线程池。
Executors.newCachedThreadPool()
创建一个 Executor,该 Executor 使用单个工作线程在无界队列中运行。(但 要注意的是,如果在关闭前的执行过程中出现故障,导致单线程终止,那么在需要 执行后续任务时,会有新的线程取而代之)。任务保证按顺序执行,任何时候都不 会有一个以上的任务处于活动状态。与newFixedThreadPool(1)不同的是,保 证返回的执行器不能重新配置以使用额外的线程
Executors.newSingleThreadExecutor()
创建一个线程池,可以安排命令在给定延迟后运行,或定期执行。
Executors.newScheduledThreadPool(int corePoolSize)