为什么局部变量是线程安全的

例如,有三个方法 A、B、C,他们的调用关系是 A->B->C(A 调用 B,B 调用 C),在运行时,会构建出下面这样的调用栈。每个方法在调用栈里都有自己的独立空间,称为栈帧,每个栈帧里都有对应方法需要的参数和返回地址。当调用方法时,会创建新的栈帧,并压入调用栈;当方法返回时,对应的栈帧就会被自动弹出。也就是说,栈帧和方法是同生共死的。

 

 

 

那么调用栈与线程是什么关系呢?

 

两个线程可以同时用不同的参数调用相同的方法,那调用栈和线程之间是什么关系呢?答案是:每个线程都有自己独立的调用栈。因为如果不是这样,那两个线程就互相干扰了。如下面这幅图所示,线程 A、B、C 每个线程都有自己独立的调用栈。

 

 

显而易见,你应该已经知道,因为每个线程都有自己的调用栈,局部变量保存在线程各自的调用栈里面,不会共享,所以自然也就没有并发问题

那么问题来了。以下方法是会先执行哪个呢?

set(get()+1);

 

方法的调用过程:是将参数先压入调用栈之后,进行参数计算,然后才会执行方法体。

那么问题又来了。我们平常写日志有以下两种写法。

写法A:log.debug("K1"+v1+“,K2”+v2);

写法B:占位符写法,log.debug("K1{}",K2{}”,v2);

 

您觉得哪个好?

根据我们刚才的分析。A 写法虽然不会在控制台打印出,但是调用前,已经计算了K1+v1,K2+v2的值。

B这种写法仅仅是将参数压栈,而没有参数的计算。使用{}占位符是写日志的一个良好习惯。

你Get到了吗?

 

==========================================================================

  如果您觉得这篇文章对你有帮助,可以【关注我】或者【点赞

  希望我们一起在架构的路上,像鹿一样追逐,也想鹿一样优雅

==========================================================================

 

posted @ 2020-02-23 15:03  架构之路  阅读(536)  评论(0编辑  收藏  举报
========================================================================== 如果您觉得这篇文章对你有帮助,可以【关注我】或者【点赞】,希望我们一起在架构的路上,并肩齐行 ==========================================================================