Java并发中偏向锁、轻量级锁和重量级锁的原理

重量级锁的原理与实战 重量级锁 阅读详情

重量级锁

Java的对象头中的MarkWord

32位操作系统:

64位操作系统:

Monitor

  • 当使用synchronized获得锁时:
synchronized(obj){//重量级锁
    //临界区代码
}

obj对象的MarkWord中的指针(ptr_to_heavyweight_monitor)指向一个 OS提供的 Monitor对象

Monitor中的Owner记录谁是这个锁的主人。

  • 当另一个对象也要获取obj锁时:

发现obj所指向的Monitor的所有者为Thread1,此时Thread2加入 阻塞队列

  • 当Thread1执行完毕,释放锁后,虚拟机从obj对象指指向的Monitor的EntryList中唤醒一个线程,赋给它锁。

轻量级锁

使用场景:如果一个对象虽然有多个线程访问,但是多线程访问的时间是错开的(没有竞争),那么可以使用 轻量级锁 来优化。

轻量级锁的语法仍然是synchronized

static final Object obj = new Object();
public static void method1(){
    synchronized(obj){ //1 加锁
        method2();
    }//4
}

public static void method2(){
    synchronized(obj){ //2
        ...
    }//3
}

加锁:

  • 在栈帧中创建锁记录(Lock Record)对象(代码1):

左边是栈帧,右边是Java堆中的obj对象,每个线程的栈帧都会包含一个锁记录的结构,其中存储了锁定对象的Mark Word。

  • 让锁记录中Object reference指向锁对象,并尝试使用cas替换Object的Mark Word,将Mark Word的值存入锁记录。

  • 如果cas替换成功,对象头中存储了锁记录地址和状态00,表示由该线程给对象加锁

  • 如果cas失败,有两种情况:
  1. 如果有其它线程持有了obj的轻量级锁,这是表明有竞争,进入锁膨胀过程

  2. 如果是自己执行了synchronized锁重入 (代码中2的位置),那么再添加一条LockRecord作为重入的计数

这里也会进行cas替换操作,但是会失败。

解锁:

  • 在代码3的位置,退出synchronized代码块,如果有取值为null的所记录,表示有重入,这是重置锁记录,表示重入计数减一

  • 在代码4的位置,退出synchronized代码块,此时所记录的值不为null,这是使用cas将Mark Word的值恢复给obj对象头
  1. 成功,解锁成功

  2. 失败,说明轻量级锁进行了膨胀或已经升级为重量级锁,进入重量级锁解锁流程

锁膨胀

static final Object obj = new Object();
public static void method1(){
    synchronized(obj){ //1 加锁
        method2();
    }//4
}

Thread-0执行method1方法,获得到轻量级锁,此时Thread-1执行method1方法,获取轻量级锁失败,进入锁膨胀流程:

  • 为ojb对象申请 Monitor 锁,让obj指向重量级锁地址,并且对象头所标志位改为10

  • 然后自己进入Monitor的EntryList 进入阻塞队列

  • 当Thread-0 退出同步块解锁时,使用cas将Mark Word的值恢复给对象头,失败。这时会进入 重量级解锁流程,即按照Monitor地址找到Monitor对象,设置Owner为null,唤醒EntryList中BLOCKED线程

自旋优化

当轻量级锁竞争时,会先进行自旋等待锁,如果自旋没有获得锁,才会膨胀为重量级锁

偏向锁

轻量级锁在每次锁重入时,仍然需要执行CAS操作,JAVA 6 中引入了偏向锁,来优化锁轻量级锁的锁重入。

static final Object obj = new Object();//1
public static void method1(){
    synchronized(obj){ //2
        method2();
    }//5
}
public static vpid method2(){
    synchronized(obj){ //3
        //临界区
    }//4
}
  • 1: 此时obj的对象头的Mark Word为:

  • 2:假设Thread-1是第一个获取该锁的线程,其线程ID为100,那么此时的Mark Word为:

  • 3:这里是一个锁重入,此时obj的对象头的Mark Word与2一样

  • 4:在重入锁释放锁的时候,偏向锁使用了一种 等到竞争出现才释放锁 的机制,这里也不会改变Mark Word ,同理在代码5处释放锁的时候也不会改变对象头

public static void test1(){
    Object lock = new Object();
    Thread t1 = new Thread(()->{
        log.info(getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
        synchronized (lock){
            log.info(getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
        }
        log.info(getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
    },"t1");
    t1.start();
    Thread t2 = new Thread(()->{
        try {
            t1.join();//等待t1线程终止
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info(getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
        synchronized (lock){
            log.info(getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
        }
        log.info(getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
    },"t2");
    t2.start();
}

运行结果:

从上面的运行结果可以看到:t2线程在获取锁的时候,因为对象头的线程id不是t2线程的id,所以偏向锁 升级为了轻量级锁;并且在释放锁之后,lock对象的Mark Word 被设置为无锁状态(001),那么下次线程获取改锁时会是一个 轻量级锁。

偏向锁撤销

  • hashcode
Object lock = new Object();
log.info(getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
d.hashCode();
log.info(getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));

对象的哈希码是存放在Mark Word 中的,但是一旦存放了哈希码,Mark Word就没有多余的空间来存放线程Id了,此时lock对象的Mark Word 的锁状态就变为了无锁(001)。

  • 其他线程竞争锁

如前面demo的结果所示,t2线程在t1线程终止之后获得了一个轻量级锁。t2在申请锁的过程中,偏向锁被撤销,然后升级为轻量级锁赋给t2线程,t2线程释放锁后,lock对象的锁状态为无锁状态。

偏向锁的批量重偏向

在上面的偏向锁撤销中,我们发现当一个线程去竞争偏向其他线程的偏向锁时,偏向锁会撤销。偏向锁的撤销有这样一个机制:

如果有线程t竞争偏向其他的线程的次数累计达到19次,那么第19次之后竞争的偏向锁将会偏向线程t(线程t获得的不再是轻量级锁),这个机制叫做 批量重偏向。

public static void test2() throws InterruptedException {
    List<Object> locks = new ArrayList<>();
    Thread t1 = new Thread(()->{
        for (int i = 0; i < 30 ; i++){
            Object lock = new Object();
            locks.add(lock);
            log.info( i + " : {}",getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
            synchronized (lock){
                log.info( i + " : {}",getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
            }
            log.info( i + " : {}",getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
        }

    },"t1");
    t1.start();

    Thread t2 =  new Thread(()->{
        try {
            t1.join();//等待t1结束
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < 30; i++){
            Object lock = locks.get(i);
            log.info( i + " : {}",getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
            synchronized (lock){
                log.info( i + " : {}",getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
            }
            log.info( i + " : {}",getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
        }
    },"t2");
    t2.start();
}

运行结果:

可以看到第19个锁还是轻量级锁,第20个锁已经偏向了t2。

偏向锁的批量撤销

public static void test3() throws InterruptedException {
    List<Object> locks = new ArrayList<>();
    Thread t1 = new Thread(()->{
        for (int i = 0; i < 39 ; i++){
            Object lock = new Object();
            locks.add(lock);
            log.info( i + " : {}",getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
            synchronized (lock){
                log.info( i + " : {}",getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
            }
            log.info( i + " : {}",getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
        }

    },"t1");
    t1.start();

    Thread t2 =  new Thread(()->{
        try {
            t1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < 39; i++){
            Object lock;
            lock = locks.get(i);
            log.info( i + " : {}",getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
            synchronized (lock){
                log.info( i + " : {}",getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
            }
            log.info( i + " : {}",getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
        }
    },"t2");
    t2.start();

    Thread t3 =  new Thread(()->{
        try {
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < 39; i++){
            Object lock;
            lock = locks.get(i);
            log.info( i + " : {}",getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
            synchronized (lock){
                log.info( i + " : {}",getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
            }
            log.info( i + " : {}",getMarkWord(ClassLayout.parseInstance(lock).toPrintable()));
        }
    },"t3");
    t3.start();
    t3.join();
    log.info("新建Lock对象:" + getMarkWord(ClassLayout.parseInstance(new Object()).toPrintable()));
    log.info("新建Object对象:" + getMarkWord(ClassLayout.parseInstance(new Object()).toPrintable()));
}

t2线程撤销了0-18个锁,19-38个锁进行了重偏向线程t2。

t3线程撤销了19-38个锁,在JVM中,Lock类型的锁一共被撤销了39次,我们看新建一个Lock对象,它的所类型如下:

从结果可以看到,新创建的Lock对象不再试偏向锁了。这就是偏向锁的批量撤销机制:

在JVM中,属于同一类型的偏向锁被撤销大于等于39次,以后新建该类型对应的锁将不再是偏向锁。

锁消除

public class LockRemoveTest{
    static int i = 0;
    public void method(){
        Object obj = new Object();
        synchronized (o){
            i++;
        }
    }
}

如果上面的代码被反复的执行超过一个阈值,JIT即时编译器就会优化这部分的字节码。其中,类似obj这样的 局部变量,它除了在本方法中可以被访问到,其他任何地方都无法访问,所以这里的同步块就没有任何意义,JIT就会优化这个同步块,取消同步操作。

我们可以使用-XX:-EliminateLocks来关闭锁消除优化。

Java并发-synchronized, 偏向锁, 轻量级锁详解 synchronized概述 synchronized就是所谓的重量级锁, 但是自从jdk1.6引入了偏向锁, 轻量级锁之后, synchronized就没有那么重了。 synchronized用法 对于普通同步方法,锁是当前实例对象 对于静态同步方法,锁是当前类的Class对象 对于同步方法块,锁是Synchonized括号里配置的对象 synchronized实现原理 任何对象都有一... 阅读详情

相关推荐

TOGAF9.2/10 认证基础知识点概览表

(考点解析:业务场景是一种重要的技术,可以在企业架构的各个阶段使用,主要是架构愿景和业务架构,但如果需要,也可以在其他架构域中使用,以直接从业务的高级需求中派生架构的特征。“哪里”可以看作是对相关企业的界定、“为什么”可以被视为组织环境中的关键驱动因素和要素、“谁”是指确定发起人利益相关者和受业务指令影响的其他主要利益相关者,以创建企业架构,并确定他们来自企业的需求和优先级、他们与企业的关系以及彼此之间所需的工作行为。它是业务驱动和业务主导的,它结 合了所有业务线的必要努力,以实现所需的能力。

2302_81497763的博客 2077

Synchronized 的锁状态

Synchronized 的锁状态 1、对象头 32位对象头 64位对象头 64位对象头比32位对象头浪费将近50%的空间,可在启动java程序时,添加+UseCompressedOops开启压缩对象头,把64位的对象头压缩位32位对象头 2、偏向锁 引入偏向锁是为了在无多线程竞争的情况下尽量减少不必要的轻量级锁执行路径,因为轻量级锁的获取及释放依赖多次CAS原子指令,而偏向锁只需...

jiongsui7605的博客 462

UE5 中 Python 编程:Python 代码加载到 UE5 中,如何供蓝图节点调用

配置 python 代码的路径,使 UE5 启动时,加载代码文件。重启之后,在蓝图中右键,就能搜索到你定义的方法了。参数为 str 字符串类型,返回值为 向量数组。注意:一定要 重启 UE5。

topcss的专栏 3997

锁的优化(偏向锁、轻量级锁、重量级锁,CAS)

为什么出现CAS? 我们知道synchronized关键字不论是实现同步方法还是同步代码块,都需要首先执行monitorenter获取到锁对象的监视器monitor,同一时刻只有一个线程可以获取到锁对象的monitor监听器,退出时需要执行monitorexit进行解锁。 monitor机制是JDK1.6之前synchronized(内建锁)底层原理,又称为JDK1.6重量级锁。线程的阻塞和唤醒均...

sophia__yu的博客 4228

Hopfield神经网络(HNN)详解

Hopfield神经网络是一种比较特殊的网络,它不像一般的神经网络那样有输入层和输出层,并且通过训练来改变神经网络中的参数,最终实现预测、识别等功能。Hopfield网络只有一群神经元节点,所有节点之间相互连接,形式如下: 虽然有些文章会画出像深度神经网络那样有输入输出的图,并且输出后又返回输入,但本质上就是多个节点之间的全连接,也就是上面的图形。Hopfield神经网络主要有两个应用:一是起到类似储存器的作用,也就是我们把多个序列或图片输入这个网络,最终这个网络会以神经元之间连接权重的形式储存这

weixin_60737527的博客 4万+

STM32L051低功耗模式下LPUART的使用

STM32L0系列低功耗UART配置代码清单及注释,大家可参考学习使用。

嵌入式工程师 2104

Java synchronized锁升级机制:5步搞懂对象头与Monitor的底层原理

掌握Java synchronized锁升级过程,深入解析对象头与Monitor底层机制。涵盖偏向锁、轻量级锁到重量级锁的5步升级流程,适用于高并发场景优化。理解synchronized核心原理,提升性能调优能力,值得收藏。

Instrulink的博客 479

M1安装homebrew报错LibreSSL SSL_read: SSL_ERROR_SYSCALL, errno 54解决方法

在mac系统中,使用homebrew可以很方便的管理包。但按照官网的说明执行命令时总是报错原因是这个资源访问有问题,那么我们可以直接使用国内的镜像。给大家推荐一个中国科学技术大学的镜像站点,里面有各种资源https言归正传,开始踩坑。......

qq_42427085的博客 1456

重量级锁的基本原理

重量级锁的基本原理 当轻量级锁膨胀到重量级锁之后,意味着线程只能被挂起阻塞来等待被唤醒了。 重量级锁的 monitor 加 了 同 步 代 码 块 以 后 , 在 字 节 码 中 会 看 到 一 个monitorenter 和 monitorexit。 每一个 JAVA 对象都会与一个监视器 monitor 关联,我们可以把它理解成为一把锁,当一个线程想要执行一段被synchronized 修饰的同步方法或者代码块时,该线程得先获取到 synchronized 修饰的对象对应的 monitor。mo

Andy的博客 1291

SAP Business One自定义表与字段实战:从零构建企业专属数据模型

本文详细介绍了如何在SAP Business One中创建自定义表与字段,从零构建企业专属数据模型。通过实战案例和避坑指南,帮助用户掌握业务适配、流程优化和权限隔离等关键技巧,提升系统灵活性和数据管理效率。特别适合需要扩展标准功能的SAP Business One用户。

weixin_28730927的博客 362

打造AI智能体员工,我用扣子复刻了华与华、奥美和金枪大叔

这事说穿了,就是你用多个AI智能体,分别扮演专业角色,构成一支能力互补、各司其职的“数字团队”。每个智能体,都有明确的角色设定、任务边界和接口形式。它不再是一个泛泛的ChatGPT,而是你手下的“品牌顾问”、“策略专家”、“文案大神”、“短视频导演”、“运营总监”。简单来说,你不再是雇一个人,而是养一群机器人打工——24小时不摸鱼,不请假,不离职。如果你是个人创业者、内容创作者、培训机构、中小企业主,其实都可以尝试构建属于你自己的“AI虚拟员工矩阵”。

互联网架构师笔记 1498

Java并发偏向锁、轻量级锁、重量级锁、synchronized和volatile的实现原理

读Java并发编程的艺术学习整理。 1. 上下文切换 CPU通过给每个线程分配CPU时间片来实现这个机制。时间片是CPU分配给各个线程的时间,因为时间片非常短,所以CPU通过不停地切换线程执行,让我们感觉多个线程是同时执行的,时间片一般是几十毫秒(ms)。 CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是,在切换前会保存上一个任务的状态,以便下次切换回这个任...

xyh的博客 1548

购物车智能检测系统:YOLO26 + PyQt5 毕设实现

YOLO26 + PyQt5 完成购物车商品检测系统:标注数据集(OpenImages 筛选 + 自制 500 张),训练 100 epoch 得到 mAP50 约 0.89,集成商品定价后输出总价。建议先用 OpenImages 预训练权重在自制数据上调优(冻住 backbone 前 50 epoch),等 loss 稳定后再解冻全量训练。

m0_64661770的博客 56

偏向锁、轻量级锁和重量级锁

为什么会有偏向锁、轻量级锁和重量级锁? 并发锁总共有4种状态:无锁状态、偏向锁状态、轻量级锁状态和重量级锁状态,每种状态在并发竞争情况下需要消耗的资源由低到高,性能由高到低。重量级锁需要通过操作系统在用户态与核心态之间切换,就像它的名字是一个重量级操作,这也是synchronized效率不高的原因,JDK1.6对synchronized进行了优化,引入了偏向锁与轻量级锁,提高了性能降低了资源消耗。 什么是偏向锁? 通过对大量数据的分析可以发现,大多数情况下锁竞争是不会发生的,往往是一个线程多次获得同一个锁,

记录各种Bug解决案例及日常学习内容 5558

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

偏向锁,轻量级锁与重量级锁的区别与膨胀

一直被这三个锁的膨胀问题所困扰,不知道到底实在什么时候会有偏向锁升级到轻量级锁,什么时候由轻量级锁升级到重量级锁。找到好久,也没有找到简洁明了的答案。        综合多个方面的描述综合自己的理解,特地记录下来。但是也有可能理解有误。    先依然描述这三个锁是什么: 这里直接从《深入理解Java虚拟机》粘贴过来。 偏向锁        Hotspot 的作者经过以往的研究发现大多

choukekai的博客 1万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Synchronized 的锁升级过程介绍(无锁 --> 偏向锁 --> 轻量级锁 --> 重量级锁 )

Synchronized 的锁升级过程介绍(无锁 --> 偏向锁 --> 轻量级锁 --> 重量级锁 )

Java 领域技术分享 5104

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

java锁机制 偏向锁-轻量级锁-重量级锁

首先粗略了解一下java对象的内存结构: 紧接着看下Mark Word的内存结构(以下都用缩写MW代表Mark Word): 再看下当一个对象被当成锁对象之后的内存结构变化: 当对象处于无锁状态时没什么好说的,它并没有多线程的情况。 当对象处于多线程环境下,我们往往是通过给对象加锁的做法来保证多线程操作共享变量的安全性,此时为了换取性能,JVM在内置锁上做了非常多的优化,膨胀式的锁分配策略就是其一。本文主要了解一个对象在多线程环境下的锁膨胀机制,大概就是无锁->偏向锁->轻量锁->重

wenhonglian的博客 951

java并发编程之Monitor、无锁、偏向锁、轻量级锁和重量级锁

一、Monitor 在理解monitor之前,先来了解一下Java对象头: 对象头 对象头是java中对象都具有的属性,是jvm在编译和运行阶段读取的信息。对象头包含三个部分: mark word 指针向类的指针 数组的长度(只有数组的对象用到) 以32位虚拟机为例: 1.概念 Monitor 被翻译为监视器或管程,可以理解为一个同步工具或一种同步机制,通常被描述为一个对象。每一个Java对象就有一把看不见的锁(C语言实现),称为内部锁或者Monitor锁。如果使用 synchronized

weixin_45803046的博客 1614

java并发之MarkWord、Monitor重量级锁,轻量级锁,偏向锁

java并发之重量级锁,轻量级锁,偏向锁,锁膨胀,自旋,monitor

cx201125的博客 2557

【JavaSE】偏向锁、轻量级锁和重量级锁,如何获取锁,如何撤销锁。

一、java对象头 锁的获取和撤销会关系到对象头,所以先来看看对象头。 Java对象头Mark Word字段存放内容: 根据竞争状态的激烈程度,锁会自动进行升级,锁不能降级(为了提高锁获取) 一、偏向锁 由于老版本的内建锁synchronized存在最大的问题:在存在线程竞争的情况下会出现线程的阻塞以及唤醒带来的性能问题,这是一种互斥同步(阻塞同步)。 大多数情况下,锁不仅不存在多线程竞争...

qq_39487033的博客 2675

Java面试--偏向锁、自旋锁、轻量级锁、重量级锁

(面试题)讲下偏向锁、自旋锁、轻量级锁、重量级锁 一、自旋锁 如果持有锁的线程能在很短时间内释放锁资源,那么那些等待竞争锁的线程就不需要做内核态和用户态之间的切换进入阻塞挂起状态,它们只需要等一等(自旋),等持有锁的线程释放锁后即可立即获取锁,这样就避免用户线程和内核的切换的消耗。 但是线程自旋是需要消耗cup的,说白了就是让cup在做无用功,如果一直获取不到锁,那线程也不能一直占用...

小刺猬 7453

Java Synchronized 偏向锁/轻量级锁/重量级锁的演变过程

前言 上篇文章已经分析了Java对象头构成、源码及其对象头的调试,本篇将分析偏向锁、轻量级锁、重量级锁的实现及其演变过程。由于涉及到c++源码,估计不少同学没兴趣看,因此重点多以图+源码辅助分析。 通过本篇文章,你将了解到: 1、什么是重量级锁 2、轻量级锁/偏向锁的由来 3、偏向锁的加锁、撤销锁、释放锁 4、轻量级锁的加锁、释放锁 5、偏向锁、轻量级锁、重量级锁的异同点 1、什么是重量级锁 简单例子 private synchronized void testLock() {

7921

Synchronized偏向锁、轻量级锁、重量级锁详解

Synchronized加锁解锁过程;偏向锁、轻量级锁、重量级锁

ccu7815058的博客 5857

深入剖析Java线程锁机制:偏向锁、轻量级锁与重量级锁

摘要: Java多线程中,偏向锁、轻量级锁和重量级锁是优化性能的关键机制。偏向锁(对象头标记线程ID)适用于单线程重复访问场景;轻量级锁通过CAS操作减少阻塞,适合低竞争环境;重量级锁基于操作系统互斥量,处理高并发但开销大。锁会从偏向→轻量级→重量级单向升级,升级过程伴随性能损耗。实际开发需根据竞争强度选择锁类型,例如单线程计数器用偏向锁,交替任务用轻量级锁,高并发连接池可能触发重量级锁,合理选择可显著提升程序效率。

没事学AI的博客 872

Java 中锁是如何一步步膨胀的(偏向锁、轻量级锁、重量级锁)

重量级锁(Mutex Lock) Synchronized 是通过对象内部的一个叫做监视器锁(monitor)来实现的。但是监视器锁本质又是依赖于底层的操作系统的 Mutex Lock 来实现的。而操作系统实现线程之间的切换这就需要从用户态转换到核心态,这个成本非常高,状态之间的转换需要相对比较长的时间,这就是为什么 Synchronized 效率低的原因。因此,这种依赖于操作系统 Mutex L...

逆水行舟 1764

Synchronized下的自旋锁、偏向锁、轻量级锁以及重量级锁(这是一篇有味道的博客)

在理解Synchronized中的锁时,需要先了解一下CAS,CAS在应用中有很多的用途。 什么是CAS? CAS的全名叫做Compare andSwap,翻译过来就是先比较再交换,在JAVA的并发包中很多的类用到了这个技术,也和数据库的乐观锁机制是一样的。 举个栗子说明下 1。第一步拿到需要修改的对象 2。第二步修改当前对象的值 3。将当前的对象...

lmx125254的博客 4794
上一篇: JVM类加载机制简单介绍
下一篇: 使用两阶段终止模型优雅的中断线程
风萧水丶寒
博客等级 码龄11年 6粉丝 63原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值