Java线程创建的方式
- 继承Thread类
- 实现Runnable接口
- 通过ExecutorService和Callable实现有返回值的线程
- 基于线程池
1、继承Thread类
使用便利,但Java是单继承,继承了Thread类就不能继承其它类了
public class ThreadTest extends Thread{
public void run() {
System.out.println(currentThread().getName());
}
public static void main(String[] args) {
ThreadTest thread1 = new ThreadTest();
ThreadTest thread2 = new ThreadTest();
thread1.start();
thread2.start();
}
}
2、实现Runnable接口
使用接口,避免了单继承的局限
public class ThreadTest implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
ThreadTest threadTest = new ThreadTest();
Thread thread1 = new Thread(threadTest, "线程1");
Thread thread2 = new Thread(threadTest, "线程2");
thread1.start();
thread2.start();
}
3、通过ExceutorService和Callable实现有返回值的线程
有时,我们需要在主线程中开启多个子线程并发执行一个任务,然后收集各个线程执行返回的结果并将最终结果汇总起来,这时就要用到Callable接口。
-
具体的实现方法为:创建一个类并实现Callable接口,在call方法中实现具体的运算逻辑并返回计算结果。
-
具体的调用过程为:创建一个线程池、一个用于接收返回结果的Future List及Callable线程实例,使用线程池提交任务并将线程执行之后的结果保存在Future中,在线程执行结束后遍历Future List中Future对象,在该对象上调用get方法就可以获取Callable线程任务返回的数据并汇总结果。
以上两种创建方法都不带返回值,而用FutureTask方法创建线程,则有返回值
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class ThreadTest implements Callable<String> {
@Override
public String call() {
String name = Thread.currentThread().getName();
return name;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<String> futureTask = new FutureTask<>(new ThreadTest());
Thread thread1 = new Thread(futureTask, "线程1");
Thread thread2 = new Thread(futureTask, "线程2");
thread1.start();
thread2.start();
System.out.println(futureTask.get());
}
}
## 基于线程池
线程是非常宝贵的计算资源,在每次需要时创建并运行结束后销毁是非常浪费系统资源的。我们可以使用缓存策略并使用线程池来创建线程,具体过程为创建一个线程池并用该线程池提交线程任务。