【Java并发入门】03 互斥锁(上):解决原子性问题
原子性问题的源头是线程切换
Q:如果禁用 CPU 线程切换是不是就解决这个问题了?
A:单核 CPU 可行,但到了多核 CPU 的时候,有可能是不同的核在处理同一个变量,即便不切换线程,也有问题。
所以,解决原子性的关键是「同一时刻只有一个线程处理该变量,也被称为互斥」。
如何做到呢?用「锁」。
一、锁模型
一)简易锁模型
一般看到的锁模型长下面这样。
但对于这个模型,会有几个疑问:
- 锁的是什么?
- 临界区的这一堆代码相关的都被锁了?
- 保护的又是什么?

二)改进后的锁模型
用下面这个模型来解释就解答了上面几个问题:
- 要保护的是临界区中的资源 R
- 因此要为 R 创建一个对应的锁 LR
- 需要处理资源 R 的时候先加锁,处理完之后解锁

要注意的是:
- 一个资源必须和锁对应,不能用 A 锁去锁 B 资源
二、Java 提供的锁技术
Java 提供了多种技术,这里仅谈及 Synchronized。
Synchronized 关键字
Java 语言提供的 synchronized 关键字,就是锁的一种实现。synchronized 关键字可以用来修饰方法,也可以用来修饰代码块。
class X {
// 修饰非静态方法
synchronized void foo() {
// 临界区
}
// 修饰静态方法
synchronized static void bar() {
// 临界区
}
// 修饰代码块
Object obj = new Object();
void baz() {
synchronized(obj) {
// 临界区
}
}
}
Q:synchronized 没看到 lock 和 unlock?
A:在编译的时候会做转换,synchronized起始的地方加锁,结束的地方解锁。
Q:那么 synchronized 锁的是什么呢?
A:当修饰静态方法时,锁定的是当前类的 Class 对象,在上面的例子中就是 Class X;
当修饰非静态方法时,锁定的是当前实例对象 this。
当修饰代码块时,括号中写的是啥就锁啥。
(可能不准确)
Class 对象是用来保存类信息的,可以理解为元数据?
实例对象则是每一个 new 出来的特殊的个体
Synchronized 实例
public class SynchronizedTT {
private int value = 0;
//public void printValue() {
public synchronized void printValue() {
System.out.println(this.value);
}
public synchronized void addValue() throws InterruptedException {
Thread.sleep(1000);
this.value += 1;
}
}
// 开两个线程,一个先调用 addValue(),另一个后调用 printValue()
思考:如果 printValue() 不添加 synchronized 关键字,会造成什么样的结果?
A:有可能会先执行了 addValue 在执行 print 但得到的却是增加之前的数值。
三、锁和受保护资源的关系
要点:
- 一把锁可以保护多个资源
- 但是一个资源只能用一把锁保护
- 受保护资源和锁之间的关联关系是 N:1 的关系
思考:如果用多把锁锁同一个资源会出现什么情况?
下面例子:
synchronized 是不同的锁,就和没锁一样。
public class SynchronizedTT {
private static int value = 0;
public synchronized void printValue() {
System.out.println(value);
}
public synchronized static void addValue() throws InterruptedException {
Thread.sleep(1000);
value += 1;
}
}

【Java并发入门】03 互斥锁(上):解决原子性问题的更多相关文章
- Java并发编程实战 03互斥锁 解决原子性问题
文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 摘要 在上一篇文章02Java如何解决可见性和有序性问题当中,我们解决了可见性和 ...
- java 并发多线程显式锁概念简介 什么是显式锁 多线程下篇(一)
目前对于同步,仅仅介绍了一个关键字synchronized,可以用于保证线程同步的原子性.可见性.有序性 对于synchronized关键字,对于静态方法默认是以该类的class对象作为锁,对于实例方 ...
- java并发多线程显式锁Condition条件简介分析与监视器 多线程下篇(四)
Lock接口提供了方法Condition newCondition();用于获取对应锁的条件,可以在这个条件对象上调用监视器方法 可以理解为,原本借助于synchronized关键字以及锁对象,配备了 ...
- Java并发入门之FutureTask
Java并发入门之FutureTask 前言: 最近遇到一个项目需要上传图片到服务器,API要求是二进制流,那就跑慢点一点点上传. 于是对多线程从没有应用过的我,决定拿多线程直接应用于代码. 应用Ex ...
- Java并发编程:Concurrent锁机制解析
Java并发编程:Concurrent锁机制解析 */--> code {color: #FF0000} pre.src {background-color: #002b36; color: # ...
- python 并发编程 多进程 互斥锁 目录
python 并发编程 多进程 互斥锁 模拟抢票 互斥锁与join区别
- Java并发编程之验证volatile不能保证原子性
Java并发编程之验证volatile不能保证原子性 通过系列文章的学习,凯哥已经介绍了volatile的三大特性.1:保证可见性 2:不保证原子性 3:保证顺序.那么怎么来验证可见性呢?本文凯哥(凯 ...
- Java并发基础03. 传统线程互斥技术—synchronized
在多个线程同时操作相同资源的时候,就会遇到并发的问题,如银行转账啊.售票系统啊等.为了避免这些问题的出现,我们可以使用synchronized关键字来解决,下面针对synchronized常见的用法做 ...
- Java并发编程:同步锁、读写锁
之前我们说过线程安全问题可以用锁机制来解决,即线程必要要先获得锁,之后才能进行其他操作.其实在 Java 的 API 中有这样一些锁类可以提供给我们使用,与其他对象作为锁相比,它们具有更强大的功能. ...
- 悲观的并发策略——Synchronized互斥锁
volatile既然不足以保证数据同步,那么就必须要引入锁来确保.互斥锁是最常见的同步手段,在并发过程中,当多条线程对同一个共享数据竞争时,它保证共享数据同一时刻只能被一条线程使用,其他线程只有等到锁 ...
随机推荐
- 微信小程序开发总结-怀庄酒业投票活动
使用微信小程序投票活动云开发 怀庄酒业活动 使用云开发.开始准备使用django开发自己的后台,但是发现功能比较简单,使用云开发更省事 项目结构: cloudfunctions目录下是三个云函数 ba ...
- SpringSecurity基本使用
SpringSecurity web 安全管理框架 需要依赖多 shiro 轻量 SSM+Shiro SpringBoot/SpringCloud+SpringSecurity 配置用户名密码 配置文 ...
- Kubernetes 存储卷详解
转载自:https://mp.weixin.qq.com/s/Ywx3ju6FP0IShOgI757XYA Volumes 默认情况下容器中的磁盘文件是非持久化的,对于运行在容器中的应用来说面临两个问 ...
- MySQL 的七种日志总结
文章转载自:https://mp.weixin.qq.com/s/ewv7HskHvH3O7kFyOmoqgw 一.MySQL 日志分类 日志类别 说明 备注 错误日志 错误日志记录了当MySQL启动 ...
- 17. Fluentd输出插件:out_copy用法详解
copy即复制,out_copy的作用就是将日志事件复制到多个输出,这样就可以对同一份日志做不同类型的分析处理. out_copy内置于Fluentd,无需单独安装. 示例配置 <match p ...
- Spring Boot 使用 Micrometer 集成 Prometheus 监控 Java 应用性能
转载自:https://cloud.tencent.com/developer/article/1508319 文章目录1.Micrometer 介绍2.环境.软件准备3.Spring Boot 工程 ...
- SVM公式详尽推导,没有思维跳跃。
假定数据集\(T=\{(x_1,y_1),(x_2,y_2),...,(x_n,y_n)\},x_n \in R_k, y_n \in \{1,-1\}\)线性可分,SVM的优化目标是: 优化一个超平 ...
- Redis学习(1)---Redis概述
什么是NoSQL 概述 NoSQL:Not Only SQL,意思不仅仅是SQL,它是属于非关系型数据库.那什么是关系型数据库?数据结构是一种有行有列的数据库. NoSQL数据库是为了解决高并发.高可 ...
- 2020-2021 Winter Petrozavodsk Camp, Belarusian SU Contest (XXI Open Cup, Grand Prix of Belarus) 题解
题目列表 C. Brave Seekers of Unicorns D. Bank Security Unification G. Biological Software Utilities I. B ...
- 【Java】Java中的零拷贝
物理内存 计算机物理内存条的容量,比如我们买电脑会关注内存大小有多少G,这个容量就是计算机的物理内存. 虚拟内存 操作系统为每个进程分配了独立的虚拟地址空间,也就是虚拟内存,虚拟地址空间又分为用户空间 ...