线程安全性与synchronized

线程安全:多线程访问某个类时,这个类始终都能表现出正确的行为,这个类就是线程安全的。

简单的说,就是多线程执行的结果与单线程执行的结果始终一致,不会因为多线程的执行时序不同而出现不同的结果

以下是一个线程不安全的程序:

当这段代码在单线程中执行时,会得出正确的答案,而在多线程环境中,则出现了执行结果完全靠运气,结果依赖于线程之间的执行时序,显然违背了线程安全的定义:多线程访问某个类时,这个类始终都能表现出正确的行为。

为什么会出现这样的结果?

虽然count++看上去很像是一个操作,实际在执行的时候是三个独立操作:

  1. 读取count的值。

  2. 将值+1。

  3. 写入count。

当上面这一个“读取-修改-写入”的操作没有使用同步机制保证这三步操作是一个不可分割原子操作,就会出现不同线程的这三步操作交替执行。

只需要加上一些线程协调机制便可将这三步操作作为一个原子操作,比如同步锁:

以上现象有一个术语来形容,叫竞态条件,即多线程访问同一资源时,如果对资源访问顺序敏感,执行结果依赖于线程的执行顺序,则为竞态条件。

Synchronized是java内置的锁,这是一种互斥锁,只能由一个线程进入被锁保护的代码,因此这个锁保护的代码块以原子方式执行,可以提供对象锁/类锁/安全发布全局变量的功能,

Synchronized的几种用法:

1.对象锁:

2.类锁:

使用锁时需要注意的地方:

  1. 当需要锁来协调线程对某个变量的访问时,所有访问这个变量的位置需要用同一个锁。

2.使用锁时要清楚代码块的代码是否需要执行很长时间,比如网络和IO操作,如果长时间持有锁,会造成线程竞争,等待的线程有两种等待策略:

a.忙锁:自旋等待锁释放,适合代码块执行时间很短的情况。

b.闲锁:将等待的线程挂起,锁释放后在合适的时机上下文切换,有一定内存同步代价。

jvm会对synchronized代码块进行不同程度的锁膨胀,偏向锁、轻量级锁、重量级锁,这个在后面的jvm系列博文会总结到。
当代码块执行的任务需要很长时间时尽量不要加锁。

同步代码块应尽可能短小,不需要同步的代码尽量移出,代码越短小,执行时间越短,线程竞争就越少,性能和吞吐量会更好,简单说就是快进快出

一些优化synchronized互斥锁性能的方法:

  1. 分段锁。

  2. 读写锁。

线程封闭

1. ad-hoc封闭:维护线程封闭性的职责完全由程序来承担。

例如代码中不做任何同步处理,只是把线程不安全的程序做成单线程程序,只有一个线程来执行了,自然就不会存在什么竞态条件、资源竞争,不推荐使用,建议用ThreadLocal。

在volatile变量上存在一种特殊的线程封闭。只要你能确保只有单个线程对共享的volatile变量执行写入操作,那么就可以安全地在这些共享的volatile变量上执行"读取—修改—写入"的操作。这种情况下相当于将修改操作封闭在单个线程中以防止发生竞态条件,并且volatile的可见性还确保其他的线程能看到最新的值。

  1. 栈封闭

简单说就是不用全局变量,用局部变量,方法内部声明的局部变量作用域是封闭在单个线程里的,不对其它线程共享,自然就不会出现竞态条件。


为什么栈封闭的局部变量能保证线程安全呢?后面更新的JVM系列会说明运行过程中的栈帧结构。

  1. ThreadLocal

是一种更规范的维护线程封闭性的方式,使变量和持有变量的线程关联起来,每个变量都有一份自己的变量,相互隔离防止共享。

例如实现线程与用户信息的绑定:

不可变对象,不能修改,只读共享

不可变的成员变量不需要额外同步,天生线程安全,如果该成员变量是一个对象,则所有属性都需要声明为final保证不可变性。

如图static保证了jvm安全发布该变量,发布后对该类创建的所有线程都是可见的,final保证了发布后为只读,不可写。

当多线程程序存在线程安全问题时,选择解决方法的优先级应当如下:

1.能否做成无状态的不变对象。无状态是最安全的。

2.能否线程封闭。

3.采用何种同步技术。

转载于:https://www.cnblogs.com/powerjiajun/p/11564159.html

线程安全与synchronized相关推荐

  1. JAVA并发编程3_线程同步之synchronized关键字

    在上一篇博客里讲解了JAVA的线程的内存模型,见:JAVA并发编程2_线程安全&内存模型,接着上一篇提到的问题解决多线程共享资源的情况下的线程安全问题. 不安全线程分析 public clas ...

  2. 线程同步机制synchronized中锁的判断以及锁的作用范围

    当我们使用多个线程访问同一资源(可以是同一个变量.同一个文件.同一条记录等)的时候,若多个线程只有读操作,那么不会发生线程安全问题,但是如果多个线程中对资源有读和写的操作,就容易出现线程安全问题. 要 ...

  3. iOS 线程安全之@synchronized的用法

    @synchronized(self)的用法: @synchronized 的作用是创建一个互斥锁,保证此时没有其它线程对self对象进行修改.这个是objective-c的一个锁定令牌,防止self ...

  4. JAVE SE 学习day_09:sleep线程阻塞方法、守护线程、join协调线程同步方法、synchronized关键字解决多线程并发安全问题

    一.sleep线程阻塞方法 static void sleep(long ms) Thread提供的静态方法sleep可以让运行该方法的线程阻塞指定毫秒,超时后线程会自动回到RUNNABLE状态,等待 ...

  5. Java线程同步机制synchronized关键字的理解

    由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题.Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问. 需要明确的几个问题: ...

  6. Java线程同步:synchronized锁住的是代码还是对象

    在Java中,synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行.synchronized既可以加在一段代码上,也可以加在 ...

  7. 多线程,线程同步,synchronized关键字的用法

    一.什么是多线程 Java多线程实现方式主要有四种:继承Thread类.实现Runnable接口.实现Callable接口通过FutureTask包装器来创建Thread线程.使用ExecutorSe ...

  8. 【Java线程安全】 synchronized同步方法、同步块:模拟抢票、模拟取款

    synchronized的使用 大佬之所以叫大佬,就是因为他们即使一次看不懂,看二十遍也要看懂,再对萌新说:这个方法不是挺简单的嘛 1.同步方法 要注意的是,synchronized锁的不是方法,而是 ...

  9. Java线程中关于Synchronized的用法

    synchronized是Java中的关键字,是一种同步锁.它修饰的对象有以下几种:  1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代 ...

最新文章

  1. Django静态文件一瞥
  2. 关于跨域的cookie问题
  3. DropdownList绑定的两种方法
  4. oracle+创建序列自增,oracle序列详解和建立自增主键
  5. 将一个指针 free 两次之后会发生什么?
  6. Spring源码-applicationcontext.xml解析过程
  7. 经典正则表达式——常用的正则表达式
  8. days to_days_Java2Days 2012:Java EE
  9. python中垃圾回收机制_Python中的变量和垃圾回收机制
  10. OpenShift 4 - 关闭更新MachineConfig后集群节点自动重启功能
  11. 的采样方式_DR803M4水质自动采样器(岸边站自动排空型)
  12. python 运行出现flask运行时提示出错了或者报服务器出错,ValueError: View function did not return a response...
  13. Syslog日志中心服务器收集windows和linux客户端日志
  14. 干货 | 【备考PMP】 鬼知道经历了什么,成功拿下5A成绩~
  15. 纳税申报、发票识别验真:解析RPA如何应用于税务领域
  16. 科普:什么是CPU?CPU和芯片关系?CPU怎么做的?CPU有什么用?不同CPU有什么区别?我们怎么选CPU?(待补充完整)
  17. CSS进阶 如何实现圆形半圆
  18. 计算机改变世界英语作文,2013年3月3日托福独立写作范文:年轻人改变世界(英文版)...
  19. WEB页面常见安全问题
  20. 【POJ P3311】【状压DP】Hie with the Pie

热门文章

  1. Example-Based Facial Rigging
  2. Lipschitzian Optimization Without the Lipschitz Constant
  3. Function Maps: A Flexible Representation of Maps Between Shapes
  4. 多特征自动植物病害识别与检测
  5. 基于预训练深度学习算法的番茄作物病害分类
  6. Canvas 超详细
  7. 怎样设计访谈提纲_访谈提纲设计
  8. 一个完整的pytorch预训练实现图像分类,模型融合
  9. 基于深度学习算法的NLP集成工具
  10. 如何构建数据指标体系?