这也是一个很热门的面试题:
redis使用的是单线程还是多线程。
大家都知道redis的特点是高性能,低延迟。而少有人去关心它底层到底是怎么做到的。
即使关心,可能也只是停留在“在内存中处理数据,而不涉及硬盘”,由此做到的高性能。
突然问一句:redis使用的是单线程还是多线程?
立马有点懵,可能少有人去把redis的高性能和是否多线程联系在一起。
这时候小白可能会萌萌的答一句:多线程吧?
因为小白可能觉得多线程比单线程“高级”一些,肯定性能也会好。
正是由于这样的误解很容易产生,所以这个面试题受到了面试官们的喜欢。
熟悉多线程的同学应该明白,多线程其实并不一定代表性能高。
举个简单例子,HashMap是线程不安全的,而concurrentHashMap是线程安全的。
之所以线程安全,是因为concurrentHashMap底层采用分段加锁机制保证了不会有并发问题。
但同时,线程安全的代价也是concurrentHashMap的性能与HashMap相比稍逊一筹,原因也很简单,一部分性能消耗在了锁上。
同样的道理,再举一个场景,假如我们要把10条数据从A点读到B点。
方案1是单线程,方案2是2个线程去读,那么哪种方案快呢?
小白可能会认为是方案2快,因为可以一条线程读前五条,一条线程读后五条,耗时不就是方案1的一半吗?
我们来实际试验一下:
public class MultThread {
private static ArrayList<Integer> source = new ArrayList();
private static ArrayList<Integer> target = new ArrayList();
private static Logger logger = LoggerFactory.getLogger("main");
private static Executor executor = Executors.newFixedThreadPool(2);
public static void main(String[] args) {
// 初始化10条数据
for(int i = 0 ; i < 100; i ++){
source.add(i);
}
long start = System.currentTimeMillis();
//数据传输
for(int i = 0 ; i < 100; i ++){
target.add(source.get(i));
}
//executor.execute(new Runnable() {
// @Override
// public void run() {
// // 数据传输
// for(int i = 0 ; i < 50; i ++){
// target.add(source.get(i));
// }
// }
//});
//executor.execute(new Runnable() {
// @Override
// public void run() {
// // 数据传输
// for(int i = 50 ; i < 100; i ++){
// target.add(source.get(i));
// }
// }
//});
target.forEach(System.out::print);
long end = System.currentTimeMillis();
logger.info("单线程耗时:{}", end-start);
// 012345678917:41:55.948 [main] INFO main - 单线程耗时:118
// 012345678917:39:34.720 [main] INFO main - 多线程耗时:102
// 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
// 58596061626364656667686970717273747576777879808182838485868788899091929394
// 959697989917:40:38.893 [main] INFO main - 多线程耗时:114
// 0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585
// 96061626364656667686970717273747576777879808182838485868788899091929394959697989917:42:31.679
// [main] INFO main - 单线程耗时:112
}
}
10个整形数的传递
-
单线程耗时:118ms
-
多线程耗时:102ms
100个整形数的传递
-
单线程耗时:114ms
-
多线程耗时:112ms
可以看得出来,多线程和单线程效率上,并不是单纯地谁快谁慢