Java线程创建的方式

DogJay 2018-11-16 面试经验 271人已围观

在各家的面试中中,不管是校招还是社招都会出现这样的问题:线程创建的方式。正常来说你要回答三种:继承Thread类(不推崇)不要问为什么,因为Java只支持单继承的,实现Runnable接口(推崇)Java在接口实现上可以实现无数个接口,通过线程池(推崇)线程池,企业级项目必用 下面就让我来展示一下Java中线程创建的三种方式的代码实现:

## 继承Thread类 ## ```java public class Match1 { public static void main(String[] args) { // 创建一个新的线程 Runner liuxiang = new Runner(); //设置线程名称 liuxiang.setName("刘翔"); //启动线程 Runner dingjie = new Runner(); dingjie.setName("丁杰"); Runner op = new Runner(); op.setName("路飞"); liuxiang.start(); dingjie.start(); op.start(); } } /** * */ class Runner extends Thread { @Override public void run() { Integer speed = new Random().nextInt(100); for (int i = 1; i <= 100; i++) { try { // 将当前线程休眠一秒 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } //this.getName()打印当前线程的名字 Console.log(this.getName() + "已前进" + (i * speed) + "米(" + speed + "米/秒)"); } } } ``` ## 实现Runnable接口 ## ```java public class Match2 { public static void main(String[] args) { Thread liuxiang = new Thread(new Runner2()); liuxiang.setName("刘翔"); Thread dingjie = new Thread(new Runner2()); dingjie.setName("丁杰"); Thread op = new Thread(new Runner2()); op.setName("路飞"); liuxiang.start(); dingjie.start(); op.start(); } } class Runner2 implements Runnable { /** * When an object implementing interface Runnable is used * to create a thread, starting the thread causes the object's * run method to be called in that separately executing * thread. *

* The general contract of the method run is that it may * take any action whatsoever. * * @see Thread#run() */ @Override public void run() { Integer speed = new Random().nextInt(100); for (int i = 1; i <= 100; i++) { try { // 将当前线程休眠一秒 Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } //Thread.currentThread():用于获取当前执行的线程,在Runnable中是无法使用this来获取当前的线程的对象的 Console.log(Thread.currentThread().getName() + "已前进" + (i * speed) + "米(" + speed + "米/秒)"); } } } ``` ## 线程池 ## ```java public class Match3 { public static void main(String[] args) { //创建一个线程池,里面创建了3个固定的线程,Executors为调度器 ExecutorService executorService = Executors.newFixedThreadPool(3); // 实例化Callable对象 Runner3 liuxiang = new Runner3(); liuxiang.setName("刘翔"); Runner3 dingjie = new Runner3(); dingjie.setName("丁杰"); Runner3 lufei = new Runner3(); lufei.setName("路飞"); Runner3 temp = new Runner3(); // 将对象扔到线程池里面,线程池自动分配一个线程 // Future用于接受线程内部call方法的返回值 Future liuxiangFuture = executorService.submit(liuxiang); Future dingjieFutrue = executorService.submit(dingjie); Future lufeiFutrue = executorService.submit(lufei); Future tempFutrue = executorService.submit(temp); try { // 阻塞五秒 Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } // 关闭线程池,释放所有资源 executorService.shutdown(); try { Console.log("刘翔已经跑了" + liuxiangFuture.get() + "米"); Console.log("丁杰已经跑了" + dingjieFutrue.get() + "米"); Console.log("路飞已经跑了" + lufeiFutrue.get() + "米"); Console.log("temp已经跑了" + tempFutrue.get() + "米"); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } } /** * 泛型的内容为call()方法的返回值 */ class Runner3 implements Callable { private String name; public void setName(String name) { this.name = name; } /** * Computes a result, or throws an exception if unable to do so. * 实现Callable接口,允许线程返回值以及异常 * * @return computed result * * @throws Exception * if unable to compute a result */ @Override public Integer call() throws Exception { Integer speed = new Random().nextInt(100); //总共奔跑的距离 Integer distinct = 0; for (int i = 1; i <= 100; i++) { Thread.sleep(10); distinct = i * speed; Console.log(this.name + "已前进" + distinct + "米(" + speed + "米/秒)"); } return distinct; } } ``` 下面来看一下三中创建方式的优缺点:

继承Thread类 实现Runnable接口 利用线程池
优点 1.编程简单;
2.执行效率高
1.面向接口编程
2.执行效率高
1.容器管理线程
2.允许返回值与异常
缺点 1.单继承
2.无法对线程进行有效的控制
1.无法对线程组有效控制;
2.没有返回值
1.执行效率相对低;
2.编程麻烦
使用场景 不推荐使用 简单的多线程程序 企业级应用,推荐使用

吐槽(0)

文章评论

    共有0条评论

    验证码:

文章目录