前言
上一篇博客,我跟小伙伴们分享了Java多线程。下面我跟大家分享的是Java多线程的实现方式。
多线程的实现
Java多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种方式是带返回值的。
第一种:继承Thread类
Java类是支持多线程的,通过java.lang.Thread类来实现,Thread中的相关函数可以启动线程,终止线程、线程挂起等;
创建:继承Thread类,并重写run方法。
启动:创建一个该类的对象,调用start方法。
实例代码:
创建
public class MyThread extends Thread{
public void run(){
}
启动
MyThread thread = new MyThread();
thread.start();
第二种:实现Runnable接口
> 提供一个实现Runnable接口的类作为一个线程的目标对象,在初始化一个Thread类或Threed子类的线程对象时,把目标对象从Runnable得到run()方法。这个定义方法仍然可以继承其它的类。
创建:实现Runnable接口。
启动:创建Runnable的实例,创建一个Thread对象,将Runnable对象传入Thread对象,调用start方法。
实例代码(包含两种):
创建
public class MyThread implements Runnable{
public void run(){
for(int i=0;i<100;i++;){
System.out.println(Thread.currentThread().getName()+i);
try{
Thread.sleep(50)
}catch(InterruptedException e){
e.printStackTarce();
}
}
}
}
启动
Thread thread =new Thread(new MyRunnable());
thread.start();
第三种:通过 Callable 和 Future 创建线程
- 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
- 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
- 使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
- 调用 FutureTask 对象的 get() 方法来获得子线程执行结束后的返回值。
实例代码
public class CallableThreadTest implements Callable<Integer> {
public static void main(String[] args) {
CallableThreadTest ctt = new CallableThreadTest();
FutureTask<Integer> ft = new FutureTask<>(ctt);
for(int i = 0;i < 100;i++) {
System.out.println(Thread.currentThread().getName()+" 的循环变量i的值"+i);
if(i==20) {
new Thread(ft,"有返回值的线程").start();
}
}
try{
System.out.println("子线程的返回值:"+ft.get());
} catch (InterruptedException e){
e.printStackTrace();
} catch (ExecutionException e){
e.printStackTrace();
}
}
@Override
public Integer call() throws Exception {
int i = 0;
for(;i<100;i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
}
return i;
}
}
创建线程的三种方式的对比
- 采用实现 Runnable、Callable 接口的方式创见多线程时,线程类只是实现了 Runnable 接口或 Callable 接口,还可以继承其他类。
- 使用继承 Thread 类的方式创建多线程时,编写简单,如果需要访问当前线程,则无需使用 Thread.currentThread() 方法,直接使用 this 即可获得当前线程。