Java多线程实现方式主要有四种:继承Thread类、实现Runnable接口、实现Callable接口通过FutureTask包装器来创建Thread线程、使用线程池技术ExecutorService、Callable、Future实现有返回结果的多线程。
1、继承Thread类创建线程
Thread类本质上是实现了Runnable接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。
实现步骤:
1.自定义类继承Thread类。
2.复写run方法。
3.创建自定义类对象。
4.调用start方法。
//继承Thread
public class MyThread extends Thread {
@Override
//重写run
public void run() {
System.out.println("MyThread.run()");
}
public static void main(String[] args) {
//创建对象
MyThread myThread1 = new MyThread();
MyThread myThread2 = new MyThread();
//开启线程
myThread1.start();
myThread2.start();
}
}
受限于java的单继承,当一个类继承了其他类后就无法继承Thread类了。
2、实现Runnable接口创建线程
实现步骤:1.自定义类实现Runnable接口。
2.重写run方法。
3.创建一个Thread类实例,并将自定义类的实例作为参数传入。
4.调用start方法。
//1.
public class MyRunnable implements Runnable {
//2.
@Override
public void run() {
System.out.println("MyRunnable run()");
}
public static void main(String[] args) {
//3.
Thread t = new Thread(new MyRunnable());
//4.
t.start();
}
}
这种方式拜托了java单继承的缺点。但是没有返回值。
实现原理:查看Thread源码
//私有属性Runnable,可在构造方法中赋值
private Runnable target;
public void run() {
//当target不为空时,调用其run方法。
if (target != null) {
target.run();
}
}
3、实现Callable接口通过FutureTask包装器来创建Thread线程
Callable接口:
public interface Callable<V> {
V call() throws Exception;
}
FutureTask包装器结构:所以FutureTask继承了Runnable类
Future接口:Future的核心思想是:一个方法,计算过程可能非常耗时,等待方法返回,显然不明智。可以在调用方法的时候,立马返回一个Future,可以通过Future这个数据结构去控制方法f的计算过程。
这里的控制包括:
get方法:获取计算结果(如果还没计算完,也是必须等待的)
cancel方法:还没计算完,可以取消计算过程
isDone方法:判断是否计算完
isCancelled方法:判断计算是否被取消
实现步骤:1.自定义类实现Callable接口
2.创建自定义类实例
3.创建FutureTask类实例,将2中实例作为参数。
4.创建一个Thread类实例,将3中实例作为参数。
5.调用start()方法启动线程。
6.调用FutureTask实例的方法获取执行结果。
//1.
public class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("MyCallable run()");
return 10;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
//2.
MyCallable call = new MyCallable();
//3.
FutureTask<Integer> task = new FutureTask<Integer>(call);
//4.
Thread thread = new Thread(task);
//5.
thread.start();
//6.
Integer i = task.get();
System.out.println(i);
}
}
4、使用ExecutorService、Callable、Future实现有返回结果的线程.下次再记。