Java程序跑的快,全要靠线程带

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

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

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

1




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





 

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

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


Java程序跑的快,全要靠线程带


如上图示意
,业务处理流程很简单,通过多

线
程的方式接收



单,然后落入缓冲队列 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(){

@Override

public 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 方法,该方法代表了线程需要完成的任务。

@Override

public 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 方式二

Java程序跑的快,全要靠线程带

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

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

Java程序跑的快,全要靠线程带

如上面 Callable 接口源码所示,提供了一个 call 方法,可以作为线程执行体,类比着 Runnable 去看,有点像 Runnable 接口的增强版, 比 Runnable 的
 ru

方法功能感觉更强大
,只因 call 方法有返回值,并可以声明抛出异常。


Java程序跑的快,全要靠线程带

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

Java程序跑的快,全要靠线程带

这不,
J
DK1.5
 提

了 
Future
 
接口来代表
 Callable 接口
里 call 方法的返回值,并且为 Future
 
接口提供了一个实现类
 F
utrue
Task

Java程序跑的快,全要靠线程带

采用 

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

寄语写最后 

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


好了,本次就谈到这里,



一起聊技术、谈业务、喷架构,少走弯路,不踩大坑。

会持续输出原创精彩分享,敬请期待!

Java程序跑的快,全要靠线程带



推荐阅读:

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


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

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


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

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

(二)

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

(三)

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

(四)

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

(五)

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

(六)

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

原文 

http://mp.weixin.qq.com/s?__biz=MzU2MDg5NzYzNA==&mid=2247485927&idx=1&sn=ca86e449d91c389ce081e17bb1748264

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Java程序跑的快,全要靠线程带

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址