ToB企服应用市场:ToB评测及商务社交产业平台

标题: 【Java并发入门】03 互斥锁(上):解决原子性问题 [打印本页]

作者: 河曲智叟    时间: 2022-12-2 23:18
标题: 【Java并发入门】03 互斥锁(上):解决原子性问题
原子性问题的源头是线程切换
Q:如果禁用 CPU 线程切换是不是就解决这个问题了?
A:单核 CPU 可行,但到了多核 CPU 的时候,有可能是不同的核在处理同一个变量,即便不切换线程,也有问题。
所以,解决原子性的关键是「同一时刻只有一个线程处理该变量,也被称为互斥」。
如何做到呢?用「锁」。
一、锁模型

一)简易锁模型

一般看到的锁模型长下面这样。
但对于这个模型,会有几个疑问:

二)改进后的锁模型

用下面这个模型来解释就解答了上面几个问题:

要注意的是:
二、Java 提供的锁技术

Java 提供了多种技术,这里仅谈及 Synchronized。
Synchronized 关键字

Java 语言提供的 synchronized 关键字,就是锁的一种实现。synchronized 关键字可以用来修饰方法,也可以用来修饰代码块。
  1. class X {
  2.   // 修饰非静态方法
  3.   synchronized void foo() {
  4.     // 临界区
  5.   }
  6.   // 修饰静态方法
  7.   synchronized static void bar() {
  8.     // 临界区
  9.   }
  10.   // 修饰代码块
  11.   Object obj = new Object();
  12.   void baz() {
  13.     synchronized(obj) {
  14.       // 临界区
  15.     }
  16.   }
  17. }  
复制代码
Q:synchronized 没看到 lock 和 unlock?
A:在编译的时候会做转换,synchronized起始的地方加锁,结束的地方解锁。
Q:那么 synchronized 锁的是什么呢?
A:当修饰静态方法时,锁定的是当前类的 Class 对象,在上面的例子中就是 Class X;
当修饰非静态方法时,锁定的是当前实例对象 this。
当修饰代码块时,括号中写的是啥就锁啥。
(可能不准确)
Class 对象是用来保存类信息的,可以理解为元数据?
实例对象则是每一个 new 出来的特殊的个体
Synchronized 实例
  1. public class SynchronizedTT  {
  2.     private int value = 0;
  3.     //public void printValue() {
  4.     public synchronized void printValue() {
  5.         System.out.println(this.value);
  6.     }
  7.     public synchronized void addValue() throws InterruptedException {
  8.         Thread.sleep(1000);
  9.         this.value += 1;
  10.     }
  11. }
  12. // 开两个线程,一个先调用 addValue(),另一个后调用 printValue()
复制代码

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4