多线程开发之三种使用线程的方法
当我们使用线程的话有三种办法:
- 实现 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的选择:
一般来说我们都是选择实现接口,理由如下:
- 接口的话可以实现多个,但是java只能继承一个类,不能实现多重继承
- 类可能只要求可执行就好,继承整个Thread类开销过大
共同学习,共同成长,若有错误,欢迎指正。