1)、继承 Thread
2)、实现 Runnable 接口
3)、实现 Callable 接口 + FutureTask (可以拿到返回结果,可以处理异常)
4)、使用线程池
区别:1、2)不能得到返回值
3)可以获得返回值
但1、2、3都不能控制资源,会造成系统资源浪费
只有4)可以控制资源,优点是性能稳定
所以在在业务代码开发中,1、2、3)启动线程的方式都不用,应该将所有的多线程异步任务交给线程池来执行。
示例代码:
public class ThreadTest {
public static ExecutorService executorService= Executors.newFixedThreadPool(10);
public static void main(String[] args)throws Exception {
System.out.println("main start.........");
//一.extends Thread
// Thread01 thread01=new Thread01();
// new Thread(thread01).start();
//二.implements Runnable
// Runnable01 runnable01=new Runnable01();
// new Thread(runnable01).start();
//三.implements Callable
// FutureTask<Integer> futureTask=new FutureTask<>(new Callable01());
// new Thread(futureTask).start();
// //futureTask.get方法会阻塞直到拿到结果
// Integer result = futureTask.get();
// System.out.println("main end........."+result);
//四.使用线程池的方式实现异步编程
executorService.execute(new Runnable01());
}
public static class Thread01 extends Thread{
public void run(){
System.out.println("当前线程:"+Thread.currentThread().getId());
Integer i=10/2;
System.out.println("运算结果.........:"+i);
}
}
public static class Runnable01 implements Runnable{
@Override
public void run() {
System.out.println("当前线程:"+Thread.currentThread().getId());
Integer i=10/2;
System.out.println("运算结果.........:"+i);
}
}
public static class Callable01 implements Callable<Integer>{
@Override
public Integer call() throws Exception {
System.out.println("当前线程:"+Thread.currentThread().getId());
Integer i=10/2;
System.out.println("运算结果.........:"+i);
return i;
}
}
}
线程池执行有2个方法,分别是execute()和submit(),它们的区别是submit方法执行会有返回值,而,execute()方法无返回值,exeucte()只能接收实现Runnable的类,而submit可接收实现Runnable或Callable的类