博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
什么是线程安全?
阅读量:6159 次
发布时间:2019-06-21

本文共 1341 字,大约阅读时间需要 4 分钟。

  hot3.png

给“线程安全”下定义是件非常棘手的事儿。随便Google一下,就能得到成千上万像这样的定义:

1.“线程安全”的代码是指在多线程同时执行的情况下,依然能正常工作的代码。

2.一段代码,如果在多线程同时执行的情况下,能以一种安全的方式操作共享数据结构,它就是线程安全的。

还有很多类似的定义。

你不觉着类似上面这种定义非但没有传达出有用的信息,甚至让自己更加迷惑吗?尽管这样,这些定义还是被大家无奈的接受了,因为它并没有错。只是,他们没能提供任务实质性的帮助或见解。

我们怎么区别“线程安全”的类和不安全的类?甚至说“安全”到底什么意思?

在线程安全中,什么是“正确性”?

任何对“线程安全”的合理定义,其核心都是在说“正确性”的概念。所以在理解线程安全之前,我们先来搞懂什么是“正确性”。

正确性意味着一个类要符合它的规范

一个好的类规范会明确规定出类在某个时刻的状态,以及对它进行一些操作后的后置条件(postcondition)。但是,通常我们并不能为我们的类提供充分的规范说明,那我们怎么知道他们是否正确执行了?我们并不能知道,但是这并不能阻止我们去使用它,一旦我们说服了自己“这些代码能正确工作”。这种“代码信任”就非常接近我们要说的“正确性”。

现在我们可以给“线程安全”下一个不那么绕的定义:

一个类在多线程并发访问时仍能保证行为的正确性,那么它就是线程安全的类。

一个线程安全的类在被多线程并发访问时仍然能正确的执行,不管这些线程是顺序执行还是错终复杂的交叉执行。并且,被调用的代码中不需要额外的添加线程同步代码。

换句话说,线程安全的类在多线程环境下和单线程环境下运行结果总是一致的。线程安全的类在内部已经处理好了任何有关线程同步的问题,而调用者不再需要考虑线程安全问题。

例子:无状态的Servlet

关于线程安全的类有个很好的例子,就是没有全局变量的java Servlet。这样的Servlet是无状态的。

public class StatelessFactorizer implements Servlet{   public void service(ServletRequest req, ServletResponse resp)   {       BigInteger i = extractFromRequest(req);       BigInteger[] factors = factor(i);       encodeIntoResponse(resp, factors);   }}

StatelessFactorizer类每次执行后的瞬时状态只存在于service方法的局部变量中,而局部变量存储在线程私有的线程栈中。一个线程访问StatelessFactorizer不会影响到另一个线程访问StatelessFactorizer的结果,因为这两个线程没有共享状态,就好像他们在访问不同的实例。由于,一个线程对无状态对象的操作不会影响到其他线程的操作的正确性,所以无状态对象是线程安全的。

以上就是很重要的“线程安全”的概念。

 

学习愉快!

转载于:https://my.oschina.net/gooke/blog/777570

你可能感兴趣的文章
[转]Paul Adams:为社交设计
查看>>
showdialog弹出窗口刷新问题
查看>>
java
查看>>
Vue.js连接后台数据jsp页面  ̄▽ ̄
查看>>
关于程序的单元测试
查看>>
mysql内存优化
查看>>
都市求生日记第一篇
查看>>
Java集合---HashMap源码剖析
查看>>
SQL优化技巧
查看>>
thead 固定,tbody 超出滚动(附带改变滚动条样式)
查看>>
Dijkstra算法
查看>>
css 动画 和 响应式布局和兼容性
查看>>
csrf 跨站请求伪造相关以及django的中间件
查看>>
MySQL数据类型--与MySQL零距离接触2-11MySQL自动编号
查看>>
生日小助手源码运行的步骤
查看>>
Configuration python CGI in XAMPP in win-7
查看>>
bzoj 5006(洛谷 4547) [THUWC2017]Bipartite 随机二分图——期望DP
查看>>
CF 888E Maximum Subsequence——折半搜索
查看>>
欧几里德算法(辗转相除法)
查看>>
面试题1-----SVM和LR的异同
查看>>