线程安全的定义常常让人迷惑,搜索引擎会发现无数定义,比如:

  1. 多个线程同时执行也能正确工作就是线程安全的代码
  2. 多个线程同时执行能以正确的方式操纵共享数据就是线程安全的代码。

而且还有很多类似的定义

你是否认为这种定义实际上没有任何意义而且还让人更加迷惑?虽然这些定义没错,但事实是他们没有提供任何实际的帮助或观点。我们如何区分线程安全类和不安全类?我们所谓的“安全”是什么意思?

线程安全的正确性是什么?

线程安全的任何合理定义的核心是正确性的概念。因此,在了解线程安全之前,我们首先应该理解这个“正确”。

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

一个好的类规范将在任何给定的时间拥有关于一个类的状态的所有信息,在其上执行某些操作以及它的后置条件。但我们经常没有为我们的类写出足够的规范,我们怎么可能知道它们能正确的使用呢?我们不能,但这并不能阻止我们使用它们,一旦我们说服自己“代码有效”。这种“代码自信”来自于我们接近正确。

乐观地将“正确性”定义为可以被识别的东西,现在我们可以用一种不那么绕的方式定义线程安全:当一个类在从多个线程访问时继续正常运行时,它是线程安全的

不管运行时环境线程调度如何交织,只有当从多个线程访问它行为正确,以及调用代码的部分没有额外的同步或其他协调,那么这个类是线程安全的

如果这个宽泛的“正确性”让你觉得比较烦,那么您可能会认为线程安全类是一个在并发环境中比单线程环境中更糟的类。线程安全类封装了所需的同步,这样客户端就不必提供自己的同步。

示例:无状态servlet

线程安全类的一个很好的例子是java servlet没有字段(fields)和引用(references),没有来自别的类的字段,它们是无状态的。

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

在特定计算瞬间数据仅存储在正在在执行线程的堆栈上,即局部变量。一个线程访问一个statelessfactorizer不会影响另一个线程访问同一个statelessfactorizer产生的结果;因为两个线程不共享状态,就好像他们访问不同的实例。由于某个线程对无状态对象的的访问操作不会影响其他线程中操作的正确性,无状态对象是线程安全的。

这就是围绕线程安全的这个小而重要的概念

Happy Learning !!

Java 并发 – 线程安全?的更多相关文章

  1. Java 并发 线程同步

    Java 并发 线程同步 @author ixenos 同步 1.异步线程本身包含了执行时需要的数据和方法,不需要外部提供的资源和方法,在执行时也不关心与其并发执行的其他线程的状态和行为 2.然而,大 ...

  2. Java 并发 线程的优先级

    Java 并发 线程的优先级 @author ixenos 低优先级线程的执行时刻 1.在任意时刻,当有多个线程处于可运行状态时,运行系统总是挑选一个优先级最高的线程执行,只有当线程停止.退出或者由于 ...

  3. Java 并发 线程属性

    Java 并发 线程属性 @author ixenos 线程优先级 1.每当线程调度器有机会选择新线程时,首先选择具有较高优先级的线程 2.默认情况下,一个线程继承它的父线程的优先级 当在一个运行的线 ...

  4. Java 并发 线程的生命周期

    Java 并发 线程的生命周期 @author ixenos 线程的生命周期 线程状态: a)     New 新建 b)     Runnable 可运行 c)     Running 运行 (调用 ...

  5. Java并发——线程安全、线程同步、线程通信

    线程安全 进程间"共享"对象 多个“写”线程同时访问对象. 例:Timer实例的num成员,即add()方法是用的次数.即Timer实例是资源对象. class TestSync ...

  6. 从JDK源码角度看java并发线程的中断

    线程的定义给我们提供了并发执行多个任务的方式,大多数情况下我们会让每个任务都自行执行结束,这样能保证事务的一致性,但是有时我们希望在任务执行中取消任务,使线程停止.在java中要让线程安全.快速.可靠 ...

  7. Java并发——线程介绍

    前言: 互联网时代已经发展到了现在.从以前只考虑小流量到现在不得不去考虑高并发的问题.扯到了高并发的问题就要扯到线程的问题.你是否问过自己,你真正了解线程吗?还是你只知道一些其他博客里写的使用方法.下 ...

  8. java并发线程池---了解ThreadPoolExecutor就够了

    总结:线程池的特点是,在线程的数量=corePoolSize后,仅任务队列满了之后,才会从任务队列中取出一个任务,然后构造一个新的线程,循环往复直到线程数量达到maximumPoolSize执行拒绝策 ...

  9. java 并发——线程

    一.前言 前一篇文章总结了对 java 并发中的内置锁的理解,这篇文章来说说线程 ,并发与线程总有剪不断理还乱的关系.关于 java 线程的基本概念.线程与进程的关系以及如何创建线程,想必大家都很清楚 ...

  10. Java并发--线程池的使用

    在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统 ...

随机推荐

  1. MySQL性能优化之参数配置

    1.目的: 通过根据服务器目前状况,修改Mysql的系统参数,达到合理利用服务器现有资源,最大合理的提高MySQL性能. 2.服务器参数: 32G内存.4个CPU,每个CPU 8核. 3.MySQL目 ...

  2. 机器学习笔记-1 Linear Regression with Multiple Variables(week 2)

    1. Multiple Features note:X0 is equal to 1 2. Feature Scaling Idea: make sure features are on a simi ...

  3. JQuery hover鼠标变换

    一般而言,我们为非按钮.链接等元素添加hover事件时,虽然能够处理悬停事件,但是鼠标却并没有变化,会造成悬停事件不明显的结果,为此,我们可以添加CSS样式cursor:pointer,使得该元素的悬 ...

  4. hdu3336 kmp

    It is well known that AekdyCoin is good at string problems as well as number theory problems. When g ...

  5. ubuntu16.04 编译运行 LSD-SLAM

    下载编译LSDSLAM,可能会出现 CreateGlutWindowAndWind is not a member of pangolin 以及 该函数参数报错的问题: 原因是在新的pangolin版 ...

  6. Jquery ajaxSubmit()的浏览器兼容问题

    form.ajaxSubmit({ 2 beforeSubmit: function() { 3 if (FinanceUtil.validate(form)) { 4 FinanceUtil.loa ...

  7. DelayQueue的原理和使用浅谈

    在谈到DelayQueue的使用和原理的时候,我们首先介绍一下DelayQueue,DelayQueue是一个无界阻塞队列,只有在延迟期满时才能从中提取元素.该队列的头部是延迟期满后保存时间最长的De ...

  8. 用ajax写分页查询-----2017-05-17

    要写分页,首先你得清楚,一页你想显示多少条信息?如何计算总共显示的页数? 先说一下思路: (1)从数据库读取数据,以chenai表为例,读取所有留言信息.并能够实现输入发送者,可以查询该发送者的留言总 ...

  9. 升讯威微信营销系统开发实践:(5) Github 源码:微信接口的 .NET 封装。

    微信开发系列教程,将以一个实际的微信平台项目为案例,深入浅出的讲解微信开发.应用各环节的实现方案和技术细节. 本系列教程的最终目标是完成一个功能完善并达到高可用性能指标的微信管理软件,所以除了与微信本 ...

  10. Linux学习第一步(虚拟机的和镜像文件的安装)

    一.安装虚拟机(本文以vmware workstation 12为例) 1.在网上所有虚拟机并下载. 2.找到下载文件安装好 3.一直下一步 4.接下来的就是选择安装的目录了,当然如果你的电脑c盘够大 ...