前言

上一篇博客,我跟小伙伴们分享了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 创建线程

  1. 创建 Callable 接口的实现类,并实现 call() 方法,该 call() 方法将作为线程执行体,并且有返回值。
  2. 创建 Callable 实现类的实例,使用 FutureTask 类来包装 Callable 对象,该 FutureTask 对象封装了该 Callable 对象的 call() 方法的返回值。
  3. 使用 FutureTask 对象作为 Thread 对象的 target 创建并启动新线程。
  4. 调用 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;  
    }  
}

创建线程的三种方式的对比

  1. 采用实现 Runnable、Callable 接口的方式创见多线程时,线程类只是实现了 Runnable 接口或 Callable 接口,还可以继承其他类。
  2. 使用继承 Thread 类的方式创建多线程时,编写简单,如果需要访问当前线程,则无需使用 Thread.currentThread() 方法,直接使用 this 即可获得当前线程。