首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
SAAS
ToB门户
了解全球最新的ToB事件
论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
微博
Follow
记录
Doing
博客
Blog
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
排行榜
Ranklist
相册
Album
应用中心
qidao123.com ToB IT社区-企服评测·应用市场
»
论坛
›
软件与程序人生
›
后端开发
›
Java
›
【Java并发入门】03 互斥锁(上):解决原子性问题 ...
返回列表
发新帖
【Java并发入门】03 互斥锁(上):解决原子性问题
[复制链接]
发表于 2022-12-2 23:18:34
|
显示全部楼层
|
阅读模式
原子性问题的源头是
线程切换
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()
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有账号?
立即注册
×
回复
使用道具
举报
返回列表
河曲智叟
+ 我要发帖
登录后关闭弹窗
登录参与点评抽奖 加入IT实名职场社区
去登录
微信订阅号
微信服务号
微信客服(加群)
H5
小程序
快速回复
返回顶部
返回列表