实现 Java 多线程的方式有四种:
- 继承Thread类,重写run方法
- 实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象作为Thread构造函数的参数
- 通过Callable和FutureTask创建线程
- 通过线程池创建线程
第一种:继承 Thread 类,重写 run 方法
package com.example.thread;
public class ThreadTest {
public static void main(String[] args) {
Thread myThread1=new MyThread();
Thread myThread2=new MyThread();
myThread1.start();
myThread2.start();
}
}
/**
* 线程类
*/
class MyThread extends Thread{
private int i=0;
public void run() {
for(i=0;i<100;i++){
System.out.println(Thread.currentThread().getName()+" : "+i);
}
}
}
第二种:实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象作为Thread构造函数的参数
package com.example.thread;
public class ThreadTest02 {
public static void main(String[] args) {
Runnable myRunnable1=new MyRunnable();
Runnable myRunnable2=new MyRunnable();
Thread thread1=new Thread(myRunnable1);
Thread thread2=new Thread(myRunnable2);
thread1.start();
thread2.start();
}
}
/**
* 实现 Runnable 接口
*/
class MyRunnable implements Runnable{
private int i=0;
public void run() {
for(i=0;i<100;i++){
System.out.println(Thread.currentThread().getName() + " : " + i);
}
}
}
第三种:通过Callable和FutureTask创建线程
package com.example.thread;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class ThreadTest03 {
public static void main(String[] args) {
Callable<Integer> myCallable=new MyCallable();
FutureTask<Integer> ft=new FutureTask<Integer>(myCallable);
Thread thread=new Thread(ft);
thread.start();
try {
int sum=ft.get();
System.out.println("sum "+" : "+sum);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
/*
* 实现了 Callable 接口
*/
class MyCallable implements Callable<Integer>{
private int i=0;
public Integer call() throws Exception {
int sum = 0;
for (; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
sum += i;
}
return sum;
}
}
第四种:通过线程池创建线程
package com.example.thread;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadTest04 {
public static void main(String[] args) {
ExecutorService executorService=Executors.newFixedThreadPool(2);
Runnable runnable=new Runnable(){
public void run() {
System.out.println(Thread.currentThread().getName());
}
};
executorService.submit(runnable);
executorService.shutdown();
}
}
分析:四种方法,底层都是实现了 Runnable 接口。
第一种:Thread 类继承了 Runnable 接口,源码如下:
第二种:Runnable 接口实现对象作为参数传入 Thread 构造函数中,Thread 构造函数方法如下:
进入 init() 方法, 发现传入的 target 赋给了 Thread 对象的成员变量 target
Thread 类继承了 Runnable 接口,重写 Runnbale 接口的 Runnable 接口的 run() 方法,而此 run() 方法执行的是 传入的 target 的 run() 方法
第三种: 通过Callable和FutureTask创建线程
源码分析:FutureTask实现了 RunnableFuture 接口,而 RunnableFuture 接口继承了 Runnable 接口。
Callable 接口的实现类的实例化对象作为参数传入到 FutureTask 的构造函数,构造函数中将其赋给成员变量 callbale
FutureTask 继承了 Runnable 接口,重写 run() 方法,run() 方法执行的是传入的 Callable 接口的实现类的实例化对象的 call() 方法:
注:之后的源码分析与第二种多线程实现源码分析一致,将 Runnable 接口的实现类的实例化对象传入 Thread 的构造方法。
第四种: 通过线程池创建线程,传入的是 Runnable 接口,最后执行的也是 Runnbale 接口中的 run()方法。