## Java实现多线程的方式及三种方式的区别 有三种使用线程的方法: * 实现 Runnable 接口; * 实现 Callable 接口; * 继承 Thread 类。 实现 Runnable 和 Callable 接口的类只能当做一个可以在线程中运行的任务,不是真正意义上的线程,因此最后还需要通过 Thread 来调用。可以说任务是通过线程驱动从而执行的。 ### **实现 Runnable 接口** 如果自己的类已经 extends 另一个类,就无法直接 extends Thread ,此时,可以实现一个Runnable 接口。 通过 Thread 调用 start() 方法来启动线程。 ~~~java public class MyRunnable implements Runnable { public void run() { // ... } } ~~~ ~~~java public static void main(String[] args) { MyRunnable instance = new MyRunnable(); Thread thread = new Thread(instance); thread.start(); } ~~~ ### **ExecutorService**、**Callable**、**Future**有返回值线程 有返回值的任务必须实现 Callable 接口,类似的,无返回值的任务必须 Runnable 接口。执行 Callable 任务后,可以获取一个 Future 的对象,在该对象上调用 get 就可以获取到 Callable 任务 返回的 Object 了,再结合线程池接口 ExecutorService 就可以实现传说中有返回结果的多线程 了。 ~~~java public class MyCallable implements Callable<Integer> { public Integer call() { return 123; } } ~~~ ~~~java public static void main(String[] args) throws ExecutionException, InterruptedException { MyCallable mc = new MyCallable(); FutureTask<Integer> ft = new FutureTask<>(mc); Thread thread = new Thread(ft); thread.start(); System.out.println(ft.get()); } ~~~ ### **继承 Thread 类** Thread 类本质上是实现了 Runnable 接口的一个实例,代表一个线程的实例。启动线程的唯一方 法就是通过 Thread 类的 start()实例方法。start()方法是一个 native 方法,它将启动一个新线 程,并执行 run()方法。 ~~~java public class MyThread extends Thread { public void run() { // ... } } ~~~ ~~~java public static void main(String[] args) { MyThread mt = new MyThread(); mt.start(); } ~~~ ### 实现接口 VS 继承 Thread 实现接口会更好一些,因为: * Java 不支持多重继承,因此继承了 Thread 类就无法继承其它类,但是可以实现多个接口; * 类可能只要求可执行就行,继承整个 Thread 类开销过大。 ### **基于线程池的方式** 线程和数据库连接这些资源都是非常宝贵的资源。那么每次需要的时候创建,不需要的时候销 毁,是非常浪费资源的。那么我们就可以使用缓存的策略,也就是使用线程池。 ~~~java //创建线程池 ExecutorServicethreadPool=Executors.newFixedThreadPool(10); while(true){ threadPool.execute(newRunnable(){//提交多个线程任务,并执行 @Override publicvoidrun(){ System.out.println(Thread.currentThread().getName()+"isrunning.."); try{ Thread.sleep(3000); }catch(InterruptedExceptione){ e.printStackTrace(); } } }); } ~~~