多线程开发之三种使用线程的方法

当我们使用线程的话有三种办法:

  • 实现 Runnable 接口;
  • 实现 Callable 接口;
  • 继承 Thread 类

实现 Runnable 和 Callable 接口的类只能当做一个可以在线程中运行的任务,不是真正意义上的线程,因此最后还需要通过 Thread 来调用。可以说任务是通过线程驱动从而执行的。

实现Runnable接口:

需要实现run方法,通过Thread的star()方法启动线程

/**
 * 创建线程三种方法:
 * 二:实现Runnable接口
 * */
public class test2 implements Runnable{

    @Override
    public void run() {
        try {
            Thread.sleep(500);
            System.out.println(Thread.currentThread()+" running..");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        test2 t = new test2();
        for (int i = 0; i < 3; i++) {
            Thread thread = new Thread(t);
            thread.start();
        }
    }
}

实现Callable接口:

可以通过FuntureTask封装返回值,是三种方法中唯一一种带返回值的

/**
 * 创建线程三种方法:
 * 三:实现Callable<>接口,带返回值
 * */

public class test3 implements Callable<String> {

    int index;
    test3(int index){
        this.index = index;
    }

    @Override
    public String call() throws Exception {
        Thread.sleep(200);
        return "线程"+index;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        for (int i = 0; i < 3; i++) {
            test3 t = new test3(i);
            FutureTask<String> ft = new FutureTask<>(t);
            Thread thread = new Thread(ft);
            thread.start();
            System.out.println(ft.get());
        }
    }
}

继承Thread类:

因为Thread类也实现了Runnable接口,所以也要实现run()方法

当调用start()方法的时候,虚拟机会将该线程放入就绪队列中等待被调度,当一个线程被调度的时候会执行该线程的run()方法

/**
 * 创建线程三种方法:
 * 一:继承Thread
 * */

public class test1 extends Thread{

    public test1(String name){
        super(name);
    }

    public String toString(){
        return getName();
    }

    @Override
    public void run() {
        try {
            sleep(1);
            System.out.println(Thread.currentThread() + " running...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 3; i++) {
            String name = "线程"+i;
            new test1(name).start();
        }
    }
}

那么我们要如何选择这几种实现方式呢?

实现接口与继承Thread的选择:

一般来说我们都是选择实现接口,理由如下:

  1. 接口的话可以实现多个,但是java只能继承一个类,不能实现多重继承
  2. 类可能只要求可执行就好,继承整个Thread类开销过大

共同学习,共同成长,若有错误,欢迎指正。

posted @ 2019-03-14 16:15  Cyrus丶  阅读(282)  评论(0编辑  收藏  举报