面试过程中,各面试官一般都会教科书式的问你几个多线程的问题,但又不知从何问起。于是就来一句,你了解多线程吗?拜托,这个有好伤自尊的!
相信老司机们对于java的多线程问题处理,稳如老狗了。你问我了解不?都懒得理你。
不过,既然是面对的是面试官,那你还一一说来。
今天我们就从多个角度来领略下多线程技术吧!
1. 为什么会有多线程?
其实有的语言是没有多线程的概念的,而java则是从一出生便有了多线程天赋。为什么?
多线程技术一般又被叫做并发编程,目的是为了程序运行得更快。
其基本原理是,是由cpu进行不同线程的调度,从而实现多个线程的同时运行效果。
多进程和多线程类似,只是多进程不会共享内存资源,切换开销更大,所以多线程是更明智的选择。
而在计算机出现早期,或者也许你也能找到单核的cpu,这时候的多线程是通过不停地切换唯一一个可以运行的线程来实现的,由于切换速度比较快,所以感觉就是多线程同时在运行了。在这种情况下,多线程与多进程等同的。但是,至少也让用户有了可以同时处理多任务的能力了,也是很有用的。
而当下的多核cpu时代,则是真正可以同时运行多个线程的时代,什么四核八线程,八核八线程.... 意味着可以同时并行n个线程。如果我们能让所有可用的线程都利用起来,那么我们的程序运行速度或者说整体性能将会得到极大提升。这是我们技术人员的目标。
2. 多线程就一定快吗?(简略)
看起来,多线程确实挺好,但是凡事皆有度。过尤不及。
如果只运行与cpu能力范围内的n线程,那是绝对ok的。但当你线程数超过这个n时,就会涉及到cpu的调度问题,调度时即会涉及一个上下文切换问题,这是要耗费时间和资源的东西。当cpu疲于奔命调度切换时,则多线程就是一个负担了。
3. 多线程主要注意什么问题?(简略)
多线程要注意的问题多了去了,毕竟这是一门不简单的学问,但是我们也可以总结下:
1. 线程安全性问题;如果连正确性都无法保障,谈性能有何意义?
2. 资源隔离问题;是你就是你的,不是你的就不是你的。
3. 可读性问题;如果为了多线程,将代码搞得一团糟,是否值得?
4. 外部环境问题;如果外部环境很糟糕,那么你内部性能再好,你能把压力给外部吗?
4. 创建多线程的方式?(简略)
这个问题确实有点low, 不过也是一个体现真实实践的地方!
1. 继承Thread类,然后 new MyThread.start();
2. 继承Runnable类, 然后 new Thread(runnable).start();
3. 继承Callable类,然后使用 ExecutorService.submit(callable);
4. 使用线程池技术,直接创建n个线程,将上面的方法再来一遍,new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); 简化版: Executors.newFixedThreadPool(n).submit(runnable);
5. 来点实际的场景?(重点)
理论始终太枯燥,不如来点实际的。
有同学说,我平时就写写业务代码,而业务代码基本由用户触发,一条线程走到底,哪来的多线程实践?
好,我们可以就这个问题来说下,这种业务的多线程:
1. 比如一个http请求,对应一个响应,如果不使用多线程,会怎么样?我们可以简单地写一个socket服务器,进行处理业务,但是这绝对不是你想看到的。比如我们常用的 spring+tomcat, 哪里没有用到多线程技术?
http-nio-8080-exec-xxx #就是一个线程池中例子。