当前位置: 首页 > wzjs >正文

做网站asp用什么软件网站备案期间

做网站asp用什么软件,网站备案期间,关键词分析工具网站,自动做效果图的网站目录 一、线程同步与线程安全问题线程不安全Demo线程不安全的原因 二、synchronized关键字关键字锁粒度修饰对象修饰代码块修饰方法修饰静态方法修饰类 synchronized 锁总结 synchronized加锁原理MarkWordsynchronized锁升级synchronized锁原理synchronized关键字总结 其他同步…

目录

    • 一、线程同步与线程安全问题
      • 线程不安全Demo
      • 线程不安全的原因
    • 二、synchronized关键字
      • 关键字锁粒度
        • 修饰对象
        • 修饰代码块
        • 修饰方法
        • 修饰静态方法
        • 修饰类
      • synchronized 锁总结
    • synchronized加锁原理
      • MarkWord
      • synchronized锁升级
      • synchronized锁原理
      • synchronized关键字总结
    • 其他同步方式
      • 乐观锁
      • Lock类的加锁、解锁
      • 分布式锁(redis)

一、线程同步与线程安全问题

线程不安全Demo

我们下面就看一个出现线程不安全情况的示例

class UnsafeThreadDemo {private int count;public MultiUnSafeDemo(int count) {this.count = count;}public void getAndIncrement() {count++;}public static void main(String[] args) throws InterruptedException {final MultiUnSafeDemo counter = new MultiUnSafeDemo(0);Thread []threads = new Thread[100];for(int i=0; i<threads.length; i++) {threads[i] = new Thread(() -> {for(int j=0; j<1000; j++) {counter.getAndIncrement();}});threads[i].start();}for(int i=0; i<threads.length; i++) {threads[i].join();}System.out.println("count: "+counter.count);}
}

运行结果,结果显示count并非100000,那又是为什么呢?
在这里插入图片描述

线程不安全的原因

问题出现在count++ 并非原子操作,i++分为三个步骤

  • 读取当前值
  • 当前值+1
  • 写回内存

线程之间的切换,可能发生在任意过程,e.g. 线程a已经加完1,但是发生线程切换,当前值被原由的线程b的值覆盖,导致实际执行100个线程的总和并非100*1000,发生线程切换的位置可能导致实际值比理论值小。

二、synchronized关键字

java中提供了一些解决线程安全问题的工具,有Lock类,有synchronized关键字,这里先介绍synchronized关键字

关键字锁粒度

修饰对象

synchronized 可以修饰对象,例如通过new ClassName() 创建的 对象,例如在代码的共享变量区域使用synchronized(this) ,可以保障线程安全,如果在第一部分的示例中使用synchronized(this) 覆盖 count++的代码块,可以保障最终的结果正确输出100000:

public class MultiUnSafeDemo {private int count;public MultiUnSafeDemo(int count) {this.count = count;}public void getAndIncrement() {synchronized (this) {count++;}}public static void main(String[] args) throws InterruptedException {final MultiUnSafeDemo counter = new MultiUnSafeDemo(0);Thread []threads = new Thread[100];for(int i=0; i<threads.length; i++) {threads[i] = new Thread(() -> {for(int j=0; j<1000; j++) {counter.getAndIncrement();}});threads[i].start();}for(int i=0; i<threads.length; i++) {threads[i].join();}System.out.println("count: "+counter.count);}
}

在这里插入图片描述
此时,由于代码的getAndIncrement方法被对象调用,因此synchronized (this) 等价于对象锁,锁的是调用这个方法的对象。通过this对象调用方法的synchornized,实现非原子性的**count++**操作的同步。

修饰代码块

除了修饰对象,可以将synchronized关键字修饰代码中共享变量的区域,保证操作共享变量的一致性。

public class Cache {private final Object lock = new Object();private Map<String, String> data = new HashMap<>();public void put(String key, String value) {synchronized (lock) { // 锁定私有对象,避免暴露锁data.put(key, value);}}
}

上述示例中,synchronized关键字修饰lock这个类的变量,实现操作data这个hashMap的线程同步性

修饰方法

可以将synchornized关键字添加到方法前,调用方法的时候会实现多线程的同步

  public synchronized void getAndIncrement() {count++;}

效果和在方法内部增加synchronized () {} 代码块相同,都是锁定这个实例

优点:实现简单,方便
缺点:可能将方法中不需要同步的部分也控制住,降低了程序的并发性。

修饰静态方法

等价于修饰类,因为静态方法的生命周期和类相同,因此在静态方法上加锁,锁定的是类所有实例,在一台机器上的对象实例都串行执行


修饰类

通过synchronized (XXXName.Class) 实现锁对象

public class DatabaseConnection {public void init() {// 同步代码块,锁定类的 Class 对象synchronized (DatabaseConnection.class) {// 初始化数据库连接(全局唯一操作)}}
}

锁的类型为 类对象,适用场景为全局:

  • 全局锁

synchronized 锁总结

Synchronized基于类、对象、方法、静态方法的使用修饰,有以下几种形式,整理为:

锁类型锁对象同步范围适用场景
对象锁对象实例,以及对象调用方法当前实例的线程非静态的示例方法
类锁Class对象所有实例的对象静态变量保护或全局操作,例如数据库连接池的初始化
同步代码块显示指定的对象代码块包含的区域同步耗时操作中的关键部分

synchronized加锁原理

MarkWord

每个 Java 对象在内存中由 对象头(Header)、实例数据(Instance Data) 和 对齐填充(Padding) 组成。synchronized 的锁信息存储在对象头中,具体分为两部分:

Mark Word:记录对象的哈希码、GC 分代年龄、锁状态标志等。

Klass Pointer:指向对象所属类的元数据。

锁状态标志 通过 Mark Word 的特定比特位表示,支持以下状态:

  • 无锁(001)
  • 偏向锁(101)
  • 轻量级锁(00)
  • 重量级锁(10)

synchronized锁升级

为了提高性能,JVM 会根据线程竞争情况动态调整锁的级别,从低开销到高开销逐步升级:

(1) 偏向锁(Biased Locking)
**适用场景:**单线程访问同步代码块。

原理:
对象头记录第一个获取锁的线程 ID(Thread ID),后续该线程无需通过 CAS 加锁和解锁。

(2) 轻量级锁(Lightweight Locking)

适用场景:
多线程交替执行,无实际竞争。

原理:

线程通过 CAS 操作 将对象头的 Mark Word 替换为指向线程栈中锁记录(Lock Record)的指针。

若成功,线程获得轻量级锁;若失败(有其他线程竞争),升级为重量级锁。

(3) 重量级锁(Heavyweight Locking)

适用场景:
多线程高竞争。

原理:

通过操作系统的 互斥量(Mutex) 实现,未获取锁的线程会被阻塞,进入内核态等待唤醒。

代价:涉及用户态到内核态的切换,性能开销较大。

synchronized锁原理

synchronized关键字修饰方法或者代码块的时候,增加了synchronized修饰的代码块在反编译为字节码的时候,都增加了monitorenter和monitorexit,monitorenter进入临界区,申请锁定资源。执行完同步代码后,monitorexit退出临界区。

synchornized修饰方法的时候,使用ACC_SYNCHRONIZED标记被修饰的方法

每个 Java 对象关联一个 监视器锁(Monitor),其本质是一个 互斥锁(Mutex)。Monitor 的实现依赖操作系统,核心操作包括:

  • 进入区(Entry Set):线程尝试获取锁,若失败则进入阻塞队列。

  • 拥有者(Owner):持有锁的线程。

  • 等待区(Wait Set):调用 wait() 的线程释放锁并进入等待状态。

synchronized关键字总结

对象头与锁状态:通过 Mark Word 记录锁状态,支持偏向锁、轻量级锁、重量级锁的升级。

锁升级机制:根据线程竞争动态调整锁级别,平衡性能与安全性。

字节码实现:依赖 monitorenter 和 monitorexit 指令,同步方法使用 ACC_SYNCHRONIZED 标记。

JVM 优化:锁消除和锁粗化减少不必要的同步开销。

适用场景:偏向锁和轻量级锁适用于低竞争场景,重量级锁应对高并发竞争。

其他同步方式

乐观锁

通过版本号,根据写入的时候的版本号和当前期望是否一致判断是否可以执行写入操作,是一种无锁的同步

Lock类的加锁、解锁

Lock的lock方法适用于单实例,单JVM的同步锁,支持可重入锁、自旋锁、中断锁

分布式锁(redis)

使用redis的单线程,根据Lua脚本和setnx保障分布式环境中的全局原子性以及超时设置

http://www.dtcms.com/wzjs/743735.html

相关文章:

  • 怎样做网站维护黔西南做网站的有几家
  • 网站建设自莱芜金点子传媒电子版
  • 揭阳做网站哪个好郑州网络营销网站优化
  • 网站建设公司画册网站开发后台数据库怎么搞
  • 做破解软件网站赚广告费怎样找到专业做网站人
  • 网站页面设计图片素材马鞍山网站建设费用
  • 专业房产网站建设公司温州微网站制作多少钱
  • 青岛网站制作系统用page打开wordpress
  • 郑州做外贸网站比较好的做网站公司
  • 网站标题改不了东莞市建设培训中心网站
  • 医院网站站群建设方案龙岩公共服务平台
  • 咸阳网站建设有哪些优化软件是什么意思
  • 网站开发技术交流群软件开发包括
  • iis网站目录权限有人说做网站赌
  • 南京商城网站开发设计手机网站建设yu
  • 可视化网站制作软件佛山关键词排名方案
  • python做简单的网站亚马逊网官网首页
  • 网站的根目录wordpress 页面改造
  • 响应式网站广州网站建设北京市朝阳区网站制作公司
  • visio网站建设流程图百度竞价价格查询
  • 网站怎么做跳站it培训课程
  • dedecms 网站 经常无法连接如何做好搜索引擎优化工作
  • 如何禁止通过ip访问网站网页设计结果分析怎么写
  • 网站开发实验的总结pc端移动端网站开发
  • 专门做橱柜衣柜效果图的网站寻找电销团队合作
  • 2003系统做网站wordpress建站后
  • 娄底优秀网站建设wordpress主题二次元
  • 外贸网站图片嵌入式软件开发工作内容
  • 百度关键词点击排名网站优化原理
  • 做资源教程网站响应式网站是什么软件做的