面试题:为什么最后两行没有运行?

个人记录:2018年,工作的第6到7个年头。
重点研究自己不太擅长的技术:分布式、高并发、大数据量、数据库优化、高性能、负载均衡等。
刷题是一种态度,是一种好习惯。


问题源头
为什么最后两行没有运行 
http://ifeve.com/question/%E4%B8%BA%E4%BB%80%E4%B9%88%E6%9C%80%E5%90%8E%E4%B8%A4%E8%A1%8C%E6%B2%A1%E6%9C%89%E8%BF%90%E8%A1%8C/


import java.util.concurrent.atomic.AtomicInteger;


//http://ifeve.com/question/为什么最后两行没有运行
//面试题 › 为什么最后两行没有运行
public class AutomicDemo {
public static int k = 0;
static AtomicInteger i = new AtomicInteger(0);


public static void main(String[] args) {


for (int m = 0; m < 10; m++) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
for (int p = 0; p < 4000; p++) {
System.out.println("i:" + i.get());
i.getAndIncrement();
System.out.println("k: " + k);
k++;
}
}
});
t.start();
}
System.out.println("最终i: --------------" + i);
System.out.println("最终k: --------------" + k);
}
}


个人看法
最开始,以为是线程出现死循环,导致最后2行代码不会执行。
但是,看多线程代码,不会死循环。
感觉这道题,更有可能是在考察 多线程安全,i++的原子性,static变量线程不安全。
但是,第1次运行结果,i:39999 k: 39999,有点怀疑人生了。
还是相信自己,可能是单机执行,i++执行太快了,没能复现出来。
又执行了2次,出现了1次k=39783,而i=39999。
验证了自己的判断。


在3次正常运行中,都没有看到最后“最终i: --------------40000”和“最终k: --------------40000”之类的输出结果。
还以为真没有执行呢?
这个根本不可能,平时多线程demo最经常的句式就是程序中的那样,最后打印结束。
不可能没有运行,不可能不打印结果。
但是,题目非要说没有运行,真是操蛋,瞎说,误导人民群众。


只好拿出程序员绝技,debug。
最后1行,加了断点,在最后一行输出了“最终...”。
比较纳闷,为啥debug的时候,会在最后一行呢?
想明白了,主线程卡在断点,子线程正常运行,主线程卡在那里的时候,k和i的值,一直在不断变化。


正常运行的时候,“最终...”正常打印了,被其它打印结果覆盖了。
哎哟。


运行3次结果
------1次----------
i:39998
k: 39782
i:39999
k: 39783




------2次------------
i:39997
k: 39997
i:39998
k: 39998
i:39999




----debug2次结果------------
k: 39995
i:39996
k: 39996
i:39997
k: 39997
i:39998
k: 39998
i:39999
k: 39999
最终i: --------------40000
最终k: --------------40000


i:39998
k: 39995
i:39999
k: 39996
最终i: --------------40000
最终k: --------------39997




网友观点
一、看来只有我一个人傻傻的把代码贴到eclipse里分析
不是没执行,是缓冲区有限,后面打印的把前面的冲掉了
把循环次数从4000改为4,或者命令行执行 java AtomicDemo >> /tmp/result  然后看result中的内容就知道了


二、main线程先于子线程结束了。最后两句前面应该调用所有子线程的join()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值