作为 Java 程序员,在技术面试时,多线程的知识多少都会被提及,这也是我面试候选人时,常聊的一个话题。

纳尼,面试中为什么常会问多线程的知识?难道面试官真的是在为难你吗?

莫急,下面一起 get 其中之奥秘。

1

 使用场景:引入多线程,明确职责,效率明显提升  

在实际项目开发中,经常会遇到订单接收处理、发送通知等场景,研发人员经常会借助多线程的方式,来提高程序的处理性能。

例如:付款业务订单处理的场景。

如上图示意,业务处理流程很简单,通过多线程的方式接收业务订单,然后落入缓冲队列 MQ,最后通过多个消费线程进行付款订单的业务处理。

很显然,在采用生产者消费者模型,进行业务处理时,能够解耦订单接收与订单处理的线程,在一定程度上能够缓解性能瓶颈对系统性能带来的影响。

例如:系统监控报警通知场景。

private final static ExecutorService EXEC = Executors.newFixedThreadPool(5); public static void asynSend(final String email, final String title, final String content){EXEC.execute(new Runnable(){@Overridepublic void run() {try {sendTextEmail(email, title, content, null);LOGGER.info("发送邮件{}成功!",email);} catch (Exception e) {LOGGER.error("发送邮件{},失败原因是{}",email, e);}}});}

随意摘的一段通过 Email 方式进行通知用户的代码,能够清楚的看到,发送的任务交给线程池去处理,进而提高程序的性能。

仅以上面两个业务场景,简单描述多线程的使用场景。而回归到生活本质,单线程程序如同只雇佣一个服务员的餐厅,他必须做完一件事情后才可以做下一件事情;而多线程程序则如同雇佣多个服务员的餐厅,各司其职,分工明确,可以同时进行多件事情,效率肯定会提高。

而在项目研发时,为什么多数同学未曾亲自开发过线程相关的代码模块呢?原因是在 Java 的世界里,很多复杂的东西都已被大佬们封装在框架或者组件里啦(eg:Tomcat、Canal、Spring 全家桶等),所以你只管利用好框架或组件,好好开发业务就好了。

2

 创建方式:“茴”字有四种写法,线程有几种创建方式呢?  

在 Java 的世界里,大家最熟悉的线程的创建方式,莫过于 Java 提供的 Thread 类和 Runnable 接口。

方式一:继承 Thread 类创建线程。

// 1. 定义 Thread 类的子类
class NotifyThread extends Thread {// 2. 重写 Thread 类的 run 方法,该方法代表了线程需要完成的任务。@Overridepublic void run() {System.out.println("报警通知");}
}/*** 线程创建的方式,so easy!* @author 一猿小讲*/
public class NotifyService {public static void main(String[] args) {//3. 创建线程对象,并调用线程对象的 start 方法启动线程new NotifyThread().start();}
}

方式二:实现 Runnable 接口创建线程。

// 1. 定义 Runnable 接口的实现类
class NotifyThread implements Runnable {// 2. 实现该接口的 run 方法,该方法是线程的执行体。public void run() {System.out.println("报警通知");}
}/*** 线程创建的方式,so easy!* @author 一猿小讲*/
public class NotifyService {public static void main(String[] args) {//3. 创建 Runnable 实现类的实例NotifyThread notifyThread = new NotifyThread();//4. 将创建的实例作为 Thread 的 target 来创建 Thread 对象new Thread(notifyThread).start();}
}

面试考点:方式一 vs 方式二。

很多同学脑袋中可能就只有上面两种创建线程的方式,面试时多数同学答到这儿就结束啦。

不过,从 JDK1.5 开始,Java 提供了 Callable 接口,提供另一种创建线程的方式。

如上面 Callable 接口源码所示,提供了一个 call 方法,可以作为线程执行体,类比着 Runnable 去看,有点像 Runnable 接口的增强版,比 Runnable 的 run 方法功能感觉更强大,只因 call 方法有返回值,并可以声明抛出异常。

如上面 Thread 源码所示,Thread 的 target 对象接收的是 Runnable,而 Callable 接口并非 Runnable 的子接口,所以 Callable 对象无法直接作为 Thread 的 target ,那该怎么办呢?另外 call 方法作为线程执行体,那方法的返回值该如何获取呢?

这不,JDK1.5 提供了 Future 接口来代表 Callable 接口里 call 方法的返回值,并且为 Future 接口提供了一个实现类 FutrueTask。

采用 Callable 和 Future 创建线程的示例代码,仔细去看很简单。

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/*** 线程创建的方式,so easy!* @author 一猿小讲*/
public class NotifyService {public static void main(String[] args) throws ExecutionException, InterruptedException {// 1. 创建 Callable 对象NotifyThread thread = new NotifyThread();// 2. 使用 FutureTask 来包装 Callable 对象FutureTask<Integer> task = new FutureTask<Integer>(thread);// 3. 实质还是以 Callable 对象来创建、并启动线程new Thread(task, "报警通知线程").start();// 4. 获取线程执行结果Integer notifyRes = task.get();System.out.println("通知结果:" + notifyRes);}
}// 1. 创建 Callable 接口的实现类,并实现 call 方法
class NotifyThread implements Callable<Integer> {// 2. 实现 call 方法,该方法将作为线程执行体public Integer call() {System.out.println("报警通知");//3. call 方法可以有返回值return 8866;}
}

3

寄语写最后 

本次,主要对技术面试时常被谈及的多线程知识,进行初步的讲解,后续会逐步进行深入。不过,若想要快速投入实战,还要靠多写、多悟,熟能生巧罢了。

好了,本次就谈到这里,一起聊技术、谈业务、喷架构,少走弯路,不踩大坑。会持续输出原创精彩分享,敬请期待!

推荐阅读:

fastjson的这些坑,你误入了没?

真实|技术人员该如何站好最后一班岗?

Java 8 的这些特性,你知道吗?

改掉这些坏习惯,还怕写不出健壮的代码?(一)

改掉这些坏习惯,还怕写不出优雅的代码?(二)

改掉这些坏习惯,还怕写不出优雅的代码?(三)

改掉这些坏习惯,还怕写不出健壮的代码?(四)

改掉这些坏习惯,还怕写不出精简的代码?(五)

改掉这些坏习惯,还怕写不出精简的代码?(六)

坚持是一种信仰,在看是一种态度!

Java程序跑的快,全要靠线程带相关推荐

  1. 《Java程序员职场全攻略:从小工到专家》连载十二:大家都是个什么身价

    大家都是个什么身价 根治这种症状的第一步,就是让其彻底看清大家到底都是什么样的身价.不过这服药可不好熬出来,薪水这个问题,从哪个角度讲可能都不一样.横向可以分为不同学历.不同技术.不同公司.不同职位. ...

  2. JAVA SE学习笔记(七):终章:Java程序设计基础笔记(全10万字)

    Java程序设计入门 ​                                              copyright © 2020 by 宇智波Akali 目录 文章目录 第1章 J ...

  3. Java程序员职场全功略 从小工到专家 连载四 IT人不容易

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 你说我容 ...

  4. Java程序员职场全功略 从小工到专家 连载三 IT语言平台

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! IT语言 ...

  5. 一个java程序启动后至少有几个线程?他们的作用是什么?_java笔记录(三、多线程)...

    1.进程和线程: 进程:正在进行的程序.每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元. 线程:进程内部的一条执行路径或者一个控制单元. 两者的区别: 一个进程至少有一个线程 ...

  6. Java程序员:快来像我这样做,3天辞退不是梦

    前言 我还记得大学毕业刚入职那会儿,进了一家不大不小的公司,拿着一份仅仅能养活自己的薪水,做着日复一日的基操. 聊天扯淡,优哉游哉!甚不快活! 尤还记得,进入公司之初,一位公司的"老&quo ...

  7. java 快速从树节点找到数据_14期每日分享Java程序员分享超全哈希相关的知识

    什么是每日分享? 饥人谷每天为大家带来一篇程序员分享!内容都来自于热爱编程.热爱生活的小伙伴们!分享的话题与编程.生活.兴趣.爱好.运动等相关! 想要每天都进步一点点的小伙伴们快点下关注吧! 今天的分 ...

  8. JAVA程序员如何快速写一个QQ机器人?

    只要你有java环境,知道maven. 建一个java版的qq机器人,只需要一条命令 通过命令创建 mvn archetype:generate -B \-DarchetypeGroupId=com. ...

  9. 表白源码全屏玫瑰java程序,表白源码全屏玫瑰

    表白源码全屏玫瑰是一款单身表白利器,让你能够通过手机就能够做到浪漫的表白,让你的表白几率大大增加,各种浪漫的表白源码一应俱全,喜欢的小伙伴们赶紧来网体验吧! [表白源码全屏玫瑰]简介 表白,或称告白意 ...

最新文章

  1. C# Combobox联动
  2. 2009年3月28日四级网络工程师 试卷答案、点评及讨论
  3. CCF 201412-2 Z字形扫描
  4. Office Open XML学习(1)-创建excel文档,并向单元格中插入字符串
  5. [转]页面回收的理解
  6. 关闭VMware声音
  7. win7使用命令提示符怎么运行C语言,Win7如何打开命令行窗口?Win7打开命令提示符的多种方法...
  8. DXP导出PCB为PDF格式的设置
  9. Solidworks与Matlab联合仿真SimMechnics下载及安装
  10. 怎么做有效沟通技巧员工培训PPT课件?
  11. jxt - 强结构文档数据表示协议
  12. DUBBO启动为啥不用web容器启动
  13. Redis删除键命令: 入门用del,老手用unlink,有何区别?
  14. 南阳理工学院计算机科学与技术分数线,2017南阳理工计算机科学与技术分数
  15. extJs 2.0学习笔记(Ext.Panel篇四)
  16. 用js获取ios时间戳,结果为NaN或不显示
  17. Q3全球太阳能企业融资规模达30亿美元 环增76%
  18. FlexRay汽车通信总线介绍及测试环境
  19. 微信公众平台环境搭建
  20. Linux03——基础篇2

热门文章

  1. 【前端系列教程之HTML5】02_HTML文档结构
  2. Linux中nginx配置图片访问路径
  3. 本地测试php邮件,php – 使用mamp在本地测试电子邮件
  4. Oracle VM VirtualBox无法全屏显示
  5. vue项目-前端请求接口报405 not allowed
  6. vue 安装cube-ui
  7. haproxy mysql 配置_HAProxy + mysql 配置
  8. 【阿冈感动】月最圆时写给乔月光的歌《爱是温暖的月光》
  9. android native ALooper AHandler
  10. 简单的字符驱动例子包括读写、装载等