多线程学习笔记:1.实现多线程的四种方式

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类

lingpaitong.png

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实现有返回结果的线程.下次再记。

猜你喜欢

转载自blog.csdn.net/qq_42283110/article/details/86584044
今日推荐