Java多线程实现方式主要有四种:继承Thread类、实现Runnable接口、实现Callable接口、使用线程池ExecutorService…
1、继承Thread类
创建一个类继承Thread
类并重写run()
方法
实例化该类new MyThread()
调用线程的start()
方法启动线程
run()
作为线程执行体被执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class MyThread extends Thread { public void run () { System.out.println("线程启动..." + Thread.currentThread().getName()); } } public class ThreadDemo { public static void main (String[] args) { MyThread myThread = new MyThread(); for (int i = 0 ; i < 3 ; i++) { new Thread(myThread).start(); } for (int i = 0 ; i < 3 ; i++) { new Thread(new MyThread()).start(); } } }
执行结果:1 2 3 4 5 6 线程启动...Thread-1 线程启动...Thread-5 线程启动...Thread-3 线程启动...Thread-2 线程启动...Thread-7 线程启动...Thread-9
2、实现Runnable接口
创建一个类实现Runnable
接口并重写run()
方法
实例化该类new MyThread()
调用线程的start()
方法启动线程
run()
作为线程执行体被执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class MyThread implements Runnable { @Override public void run () { System.out.println("线程启动..." + Thread.currentThread().getName()); } } public class RunnableDemo { public static void main (String[] args) { MyThread myThread = new MyThread(); for (int i = 0 ; i < 3 ; i++) { new Thread(myThread).start(); } } }
执行结果:1 2 3 线程启动...Thread-0 线程启动...Thread-2 线程启动...Thread-1
3、实现Callable接口
创建Callable接口的实现类,重写call()
方法作为线程执行体,该方法有返回值
创建Callable接口类的实例,使用FutureTask
类来包装该实例
将FutureTask
对象作为Thread
类的target创建启动线程
使用FutureTask
的get()
方法获取子线程call()
方法的返回值。主线程将在get()
方法处阻塞等待子线程执行完成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import java.util.concurrent.Callable;import java.util.concurrent.FutureTask;class MyThread implements Callable <String > { public String call () throws Exception { System.out.println("线程启动..." + Thread.currentThread().getName()); Thread.sleep(2000 ); return "线程返回值" ; } } public class CallableDemo { public static void main (String[] args) { MyThread myThread = new MyThread(); FutureTask<String> futureTask = new FutureTask<String>(myThread); new Thread(futureTask).start(); try { System.out.println(futureTask.get()); } catch (Exception e) { e.printStackTrace(); } } }
执行结果:
4、使用线程池ExecutorService
调用Executors
的静态工厂方法创建一个ExecutorService
线程池
创建Runnable
或Callable
实现类的实例,作为线程任务
使用ExecutorService
对象的submit()
方法提交Runnable
或Callable
的实例
使用ExecutorService
对象的shutdown()
方法关闭线程池
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class MyThread implements Runnable { @Override public void run () { System.out.println("线程启动..." + Thread.currentThread().getName()); } } public class ExecutorServiceDemo { public static void main (String[] args) { ExecutorService pool = Executors.newFixedThreadPool(3 ); for (int i = 0 ; i < 3 ; i++) { pool.submit(new MyThread()); } pool.shutdown(); } }
执行结果:1 2 3 线程启动...pool-1-thread-2 线程启动...pool-1-thread-3 线程启动...pool-1-thread-1
多线程的一些常见问题 继承Thread类和实现Runnable接口的区别?
由于Java只支持单继承,在实现Runnable接口后还可以继承其他类,而继承Thread类之后就不能在继承其他类了。所以一般使用实现Runnable接口的方法实现多线程。
Callable接口和Runnable接口的区别?
Callable接口的线程执行体是call()
,而Runnable接口的线程执行体是run()
call()
方法可以有返回值,也可以抛出异常。可以把Callable接口看做Runnable接口的增强版