Java 锁的优化策略 和 膨胀过程

Synchronized的锁膨胀艺术:深入源码的探险之旅 在Java多线程的舞台上,synchronized如同一位优雅的舞者,而锁膨胀则是她独特的舞步。从无锁到偏向锁,再到轻量级锁和重量级锁,每一步都展现出她对性能的极致追求。让我们一起欣赏这位舞者在源码的舞台上演绎的这场精彩的舞蹈吧! 阅读详情

引用文章https://www.cnblogs.com/twoheads/p/10148598.html

1. Java 锁的优化策略 和 膨胀过程

1.1 自旋锁

自选锁其实就是在拿锁时发现已经有线程拿了锁,自己如果去拿会阻塞自己,这个时候会选择进行一次忙循环尝试。也就是不停循环看是否能等到上个线程自己释放锁。这个问题是基于一个现实考量的:很多拿了锁的线程会很快释放锁。因为一般敏感的操作不会很多。当然这个是一个不能完全确定的情况,只能说总体上是一种优化。

举个例子就好比一个人要上厕所发现厕所里面有人,他可以:1,等一小会。2,跑去另外的地方上厕所。等一小会不一定能等到前一个人出来,不过如果跑去别的厕所的花费的时间肯定比等一小会结果前一个人出来了长。当然等完了结果那个人没出来还是要跑去别的地方上厕所这是最慢的。

从轻量级锁获取的流程中我们知道**,当线程在获取轻量级锁的过程中执行CAS操作失败时,是要通过自旋来获取重量级锁的。问题在于,自旋是需要消耗CPU的,如果一直获取不到锁的话,那该线程就一直处在自旋状态**,白白浪费CPU资源。解决这个问题最简单的办法就是指定自旋的次数,例如让其循环10次,如果还没获取到锁就进入阻塞状态。但是JDK采用了更聪明的方式——适应性自旋,简单来说就是线程如果自旋成功了,则下次自旋的次数会更多,如果自旋失败了,则自旋的次数就会减少。

1.2 锁粗化(Lock Coarsening)

锁粗化的概念应该比较好理解,就是将多次连接在一起的加锁、解锁操作合并为一次,将多个连续的锁扩展成一个范围更大的锁。要知道锁的取得(假如只考虑重量级MutexLock)是需要操作系统调用的,从用户态进入内核态,开销很大。于是针对这种情况也许虚拟机发现了之后会适当扩大加锁的范围(所以叫锁粗化)以避免频繁的拿锁释放锁的过程。举个例子:

package com.paddx.test.string;
 

public class StringBufferTest {

  StringBuffer stringBuffer = new StringBuffer();

 
  public void append(){

	stringBuffer.append("a");

	stringBuffer.append("b");

	stringBuffer.append("c");

  }

}

这里每次调用stringBuffer.append方法都需要加锁和解锁,如果虚拟机检测到有一系列连串的对同一个对象加锁和解锁操作,就会将其合并成一次范围更大的加锁和解锁操作,即在第一次append方法时进行加锁,最后一次append方法结束后进行解锁。

1.3 锁消除(Lock Elimination)

消除即删除不必要的加锁操作。根据代码逃逸技术,如果判断到一段代码中,堆上的数据不会逃逸出当前线程,那么可以认为这段代码是线程安全的,不必要加锁。看下面这段程序:

package com.paddx.test.concurrent;

public class SynchronizedTest02 {

  public static void main(String[] args) {

      SynchronizedTest02 test02 = new SynchronizedTest02();

      //启动预热

      for (int i = 0; i < 10000; i++) {

          i++;

      }

      long start = System.currentTimeMillis();

      for (int i = 0; i < 100000000; i++) {


          test02.append("abc", "def");

      }

      System.out.println("Time=" + (System.currentTimeMillis() - start));

  }

  public void append(String str1, String str2) {

      StringBuffer sb = new StringBuffer();

      sb.append(str1).append(str2);

  }

}

虽然StringBuffer的append是一个同步方法,但是这段程序中的StringBuffer属于一个局部变量,并且不会从该方法中逃逸出去,所以其实这过程是线程安全的,可以将锁消除。下面是我本地执行的结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WF1em4IK-1615514210955)(https://i.loli.net/2021/03/12/fWxlZ9zTNiqutcF.png)]

为了尽量减少其他因素的影响,这里禁用了偏向锁(-XX:-UseBiasedLocking)。通过上面程序,可以看出消除锁以后性能还是有比较大提升的。

1.4 锁膨胀

锁的状态总共有四种:无锁状态、偏向锁、轻量级锁和重量级锁。随着锁的竞争,锁可以从偏向锁升级到轻量级锁,再升级的重量级锁(但是锁的升级是单向的,也就是说只能从低到高升级,不会出现锁的降级)。JDK 1.6中默认是开启偏向锁和轻量级锁的,我们也可以通过-XX:-UseBiasedLocking来禁用偏向锁。

锁的状态保存在对象的头文件中,以32位的JDK为例:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f3Yx1uPv-1615514210960)(https://i.loli.net/2021/03/12/364o95wcZVTQnhY.png)]

偏向锁和轻量级锁,这两个锁既是一种优化策略,也是一种膨胀过程所以一起说。首先它们的关系是:最高效的是偏向锁,尽量使用偏向锁,如果不能(发生了竞争)就膨胀为轻量级锁,这样优化的效率不如原来高不过还是一种优化(对比重量级锁而言)。所以整个过程是尽可能地优化。

1.4.1 偏向锁

举个例子来说明偏向锁:一个仓库管理员管着钥匙,偏向锁,偏向锁就是仓库的锁头,而管理人员就是这个进程,只有找老王拿到钥匙才能够进行同步代码块的执行.此时,老张(一个线程)每一次都是老王去借,仓库管理员于是就认识了老王,直接和他说,“行,你直接拿就是不用填表格了我记得你”。此时老王就将锁头(Mark Word)上标注偏向锁标志位为"1",记录偏向线程的ID.这样偏向线程就一直持有着锁,直到竞争发生才释放锁。

下一次有线程尝试获取锁的时候,首先检查这个对象头的MarkWord是不是储存着这个线程的ID。如果是,那么直接进去而不需要任何别的操作。如果不是,那么分为两种情况。

  1. 对象的偏向锁标志位为0(当前不是偏向锁),说明已经发生了竞争,已经膨胀为轻量级锁,这时使用CAS操作尝试获得锁
  2. 偏向锁标志位为1,说明还是偏向锁不过请求的线程不是原来那个了。也就是说当前的锁可能有人获取且未释放,也有可能刚刚的老张已经释放锁了,但还偏上他。这时只需要使用CAS尝试把对象头偏向锁从原来那个线程指向目前求锁的线程。

那问题来了,此时进行CAS会不会失败呢? 当然是会的了。

1.4.1.1 加锁

偏向锁加锁发生在偏向线程第一次进入同步块时,CAS原子操作尝试更新对象的Mark Word(偏向锁标志位为"1",记录偏向线程的ID)。

1.4.1.2 撤销偏向锁

当有另一个线程来竞争锁的时候,就不能再使用偏向锁了,要膨胀为轻量级锁。
竞争线程尝试CAS更新对象头失败,会等待到全局安全点(此时不会执行任何代码)撤销偏向锁。

image.png

撤销偏向锁,会将锁置于无锁状态,即偏向锁位为0,锁标志位为01

1.4.2 轻量级锁

“轻量级”是相对于使用操作系统互斥量来实现的传统锁而言的。但是,首先需要强调一点的是,轻量级锁并不是用来代替重量级锁的,它的本意是在没有多线程竞争的前提下,减少传统的重量级锁使用产生的性能消耗。在解释轻量级锁的执行过程之前,先明白一点,轻量级锁所适应的场景是线程交替执行同步块的情况,如果存在同一时间访问同一锁的情况,就会导致轻量级锁膨胀为重量级锁。

轻量锁与偏向锁不同的是:

  1. 轻量级锁每次退出同步块都需要释放锁,而偏向锁是在竞争发生时才释放锁
  2. 每次进入退出同步块都需要CAS更新对象头
  3. 争夺轻量级锁失败时,自旋尝试抢占锁

可以看到轻量锁适合在竞争情况下使用,其自旋锁可以保证响应速度快,但自旋操作会占用CPU,所以一些计算时间长的操作不适合使用轻量级锁。

1.4.2.1 轻量级锁的加锁过程

(1)在代码进入同步块的时候,如果同步对象锁状态为无锁状态(锁标志位为“01”状态,是否为偏向锁为“0”),虚拟机首先将在当前线程的栈帧中建立一个名为锁记录(Lock Record)的空间,用于存储锁对象目前的Mark Word的拷贝,官方称之为 Displaced Mark Word。这时候线程堆栈与对象头的状态如图2.1所示。

image.png

(2)拷贝对象头中的Mark Word复制到锁记录中。

(3)拷贝成功后,虚拟机将使用CAS操作尝试将对象的Mark Word更新为指向Lock Record的指针,并将Lock record里的owner指针指向object mark word。如果更新成功,则执行步骤(4),否则执行步骤(5)。

(4)如果这个更新动作成功了,那么这个线程就拥有了该对象的锁,并且对象Mark Word的锁标志位设置为“00”,即表示此对象处于轻量级锁定状态,这时候线程堆栈与对象头的状态如图2.2所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4NQ3RzzX-1615514210964)(https://i.loli.net/2021/03/12/AoqcpBQCmUM5kzO.png)]

(5)如果这个更新操作失败了,虚拟机首先会检查对象的Mark Word是否指向当前线程的栈帧,如果是就说明当前线程已经拥有了这个对象的锁,那就可以直接进入同步块继续执行。否则说明多个线程竞争锁,轻量级锁就要膨胀为重量级锁,锁标志的状态值变为“10”,Mark Word中存储的就是指向重量级锁(互斥量)的指针,后面等待锁的线程也要进入阻塞状态。 而当前线程便尝试使用自旋来获取锁,自旋就是为了不让线程阻塞,而采用循环去获取锁的过程。

1.4.2.2 轻量级锁的解锁过程:

(1)通过CAS操作尝试把线程中复制的Displaced Mark Word对象替换当前的Mark Word。

(2)如果CAS操作成功,整个同步过程就完成了。

(3)若CAS操作失败则是出现了竞争,锁已膨胀为重量级锁了,此时需要释放锁(持有重量级锁线程的指针位为"0",锁标识位为"10")并唤醒重量锁的线程。

1.5 偏向锁、轻量级锁和重量级锁对比

锁类型优点缺点适用场景
偏向锁加锁、解锁不需要额外资源消耗,效率较高如果线程间存在锁竞争,会带来额外的解锁消耗适用只有一个线程访问同步块的情景
轻量级锁竞争的线程不会阻塞,提高了程序响应速度如果获取锁失败,会进入自旋消耗cpu针对锁占用时间短,对响应时间比较敏感的情况
重量级锁线程竞争不使用自旋,不消耗cpu线程会被阻塞,影响响应时间锁占用时间较长,对吞吐量要求较高
运维与软件实施课表 运维与软件实施课表 课程 章节编号 章节 课程地址 软件及操作系统基础 ch01 软件及操作系统基础01 实施、运维工程师基本技能:https://blog.csdn.net/qq_28189423/article/details/82700539 老毛桃制作winPE镜像:https://blog.csdn.net/qq_2818942... 阅读详情

相关推荐

Kettle入门指南:从安装到数据转换实战

本文提供Kettle(Pentaho Data Integration)的完整入门指南,涵盖从Java环境安装、软件配置到核心概念(转换与作业)的详细解析。通过实战案例,手把手教你如何将文本文件数据导出到Excel,并连接MySQL数据库进行数据导入,帮助你快速掌握这一强大ETL工具的基本使用,实现高效数据搬运与转换。

weixin_29266647的博客 448

StringBuffer的append方法的注意事项(JAVA)

 关于StringBuffer对象的append方法介绍,在Ivor Horton所著的《Java 2 入门经典(JDK 5)》(英文名:Beginning Java 2,JDK 5 Edition)中第4章数组和字符串讲解中,第4.4小节(向StringBuffer对象增加其他内容)介绍了用append()方法追加子串的功能。原文提供例子如下:    StringBuffer buf

hwctl的专栏 7581

【目标检测】基于yolov5的道路坑洼检测(附代码和数据集)

基于yolov5的道路坑洼检测(附代码和数据集)

学无止境、积少成多、厚积薄发 4620

Java锁粗化与锁消除

锁粗化通常情况下,为了保证多线程间的有效并发,会要求每个线程持有锁的时间尽可能短,但是大某些情况下,一个程序对同一个锁不间断、高频地请求、同步与释放,会消耗掉一定的系统资源,因为锁的讲求、同步与释放本身会带来性能损耗,这样高频的锁请求就反而不利于系统性能的优化了,虽然单次同步操作的时间可能很短。锁粗化...

FYHannnnnn的博客 402

uniapp - 超详细 H5 网页引入百度地图教程,附地图示例 / 获取当前设备定位的省市区、详细地址、经纬度信息 / 用户当前 IP 属地定位地理位置等等(新手小白快速上手,详细配置及使用全流程)

uniapp百度地图,uniapp百度地图ip属地定位,uniapp百度地图获取省市区详细地址经纬度等,uniapp百度地图当前用户设备定位省份市区详细所在地ip属地等详细教程示例,uniapp网页h5引入百度地图详细教程,uniapp h5网站使用百度地图详细教程,uniappH5端如何接入使用百度地图api,uniapp H5网页端百度地图获取地理位置信息,uniapp h5页面引入百度地图,uniapp h5平台百度地图获取城市信息,uniapp百度地图获取经纬度,uniapp 百度地图拿省市区用什么

🏆 前端领域优质创作者 6216

基于单片机的智能温控风扇设计

该智能温控风扇系统的设计目标是根据环境温度自动控制风扇的转速或开关状态,确保用户始终处于舒适的温度范围内。实时温度监测:通过温度传感器(如DS18B20或DHT22)实时监控环境温度。风扇控制:根据温度变化自动调节风扇的转速,温度过高时风扇加速,温度适中时风扇转速降低,达到节能与舒适平衡。LCD显示:通过LCD屏幕实时显示温度信息。无线通信:通过Wi-Fi或蓝牙模块将温度数据发送至手机或云平台,支持远程控制风扇的开关或调节转速。报警功能:温度过高或过低时,蜂鸣器发出警报,提示用户注意。

2201_76125393的博客 1154

StringBuffer append 死锁

public class Ss1 { /** * @param args */ public static void main(String args[]){ Integer i = new Integer(50); StringBuffer sb = new StringBuffer("1234"); MyThread mt1 = new MyThread(sb); m

大树叶 技术专栏 1421

T型三电平逆变器中点电位平衡详解

T型三电平逆变器(T-type Three-Level Inverter)是一种高效的多电平拓扑,相比传统NPC(Neutral Point Clamped)三电平逆变器,具有更低的开关损耗、更高效率和更简单的结构,尤其适用于中功率应用(如光伏逆变器、风电变换器和工业驱动)。(T-type Three-Level Inverter)中的应用已成为当前中高压功率变换领域(如光伏逆变器、储能PCS、电动汽车充电桩、风电并网和工业驱动)的热门方案。针对 T型逆变器,类似 NPC 的零序注入法适用。

专注于前沿技术的探索与实践,热衷于从代码逻辑、架构设计到行业应用等多维度深挖技术本质。期待在技术之路上与你共同成长~ 545

2019年12月01日总结(Java StringBuffer 和 StringBuilder 类,java append方法)

1.Java StringBuffer 和 StringBuilder 类 当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。 和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。 StringBuilder 类在 Java 5 中被提出,它和 ...

DAO1024的博客 392

【C语言】一文搞懂C语言文件操作

读写文件、文件相关库函数详解、文件缓冲区介绍

StackFrame 5657

C# USB通信实现

在C#中,我们可以利用.NET框架提供的类库和API来实现与USB设备的通信。本文将介绍如何使用C#进行USB通信,并提供相应的代码示例。以上就是使用C#进行USB通信的基本过程。通过以上代码示例,你可以实现与USB设备的简单通信,具体的实现方式和细节根据你的实际需求进行调整和扩展。命名空间,该命名空间包含了与串口通信相关的类和方法。选择需要通信的USB设备,然后使用。步骤二:获取可用的USB设备列表。首先,在你的C#项目中引入。步骤三:打开USB端口。步骤六:关闭USB端口。步骤一:引入命名空间。

PixelProX的博客 4382

Java设计模式——策略模式

行为型模式 第三种设计模式——行为型模式,共11种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 策略模式 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 con...

No_Game_No_Life_的博客 955

51单片机 DHT11温湿度传感器LCD显示+串口打印+Proteus仿真

DHT11+LCD1602+串口输出+Proteus仿真

perseverance51博客 7198

java解决策略膨胀_JAVA锁的优化和膨胀过程

转自:https://www.cnblogs.com/dsj2016/p/5714921.htmlhttps://cloud.tencent.com/developer/article/1036756复杂过程见转的另一篇:https://i.cnblogs.com/PostDone.aspx?postid=10150063&actiontip=%e5%8f%91%e5%b8%83%e6%8...

weixin_42120563的博客 166

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

深度学习工具包 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解决策略膨胀_JAVA锁的膨胀过程和优化

首先说一下锁的优化策略。1,自旋锁自选锁其实就是在拿锁时发现已经有线程拿了锁,自己如果去拿会阻塞自己,这个时候会选择进行一次忙循环尝试。也就是不停循环看是否能等到上个线程自己释放锁。这个问题是基于一个现实考量的:很多拿了锁的线程会很快释放锁。因为一般敏感的操作不会很多。当然这个是一个不能完全确定的情况,只能说总体上是一种优化。举个例子就好比一个人要上厕所发现厕所里面有人,他可以:1,等一小会。2,...

weixin_34159899的博客 99

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

java解决策略膨胀_JAVA锁的膨胀过程和优化(阿里)

阿里的人问什么是锁膨胀,答不上来,回来做了总结:关于锁的膨胀,synchronized的原理参考:深入分析Synchronized原理(阿里面试题)首先说一下锁的优化策略。1,自旋锁自旋锁其实就是在拿锁时发现已经有线程拿了锁,自己如果去拿会阻塞自己,这个时候会选择进行一次忙循环尝试。也就是不停循环看是否能等到上个线程自己释放锁。这个问题是基于一个现实考量的:很多拿了锁的线程会很快释放锁。因为一般敏...

weixin_39675926的博客 233

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

java解决策略膨胀_java锁的膨胀过程和优化

首先说一下锁的优化策略。1,自旋锁自选锁其实就是在拿锁时发现已经有线程拿了锁,自己如果去拿会阻塞自己,这个时候会选择进行一次忙循环尝试。也就是不停循环看是否能等到上个线程自己释放锁。这个问题是基于一个现实考量的:很多拿了锁的线程会很快释放锁。因为一般敏感的操作不会很多。当然这个是一个不能完全确定的情况,只能说总体上是一种优化。举个例子就好比一个人要上厕所发现厕所里面有人,他可以:1,等一小会。2,...

weixin_39927059的博客 101

syntronized锁膨胀过程

这几天在逛B站时看别人的面试过程,问到了syntronized的锁膨胀过程,突然发现自己对这块不是很了解,在网上收集了一些资料记录一下: 首先:为什么要有锁膨胀过程: 在java 1.6之前,syntronized的操作是一项非常重的操作,属于重量级锁,但是Java的开发者们发现其实很多时候锁的竞争机制不是那么激烈的,没有必要在一个同步块中采取这样消耗性能的方式来处理,因为资源的竞争,加锁解锁,涉及到了用户态和内核态的转换。 所以在Java1.6的时候,他们对这个关键字进行了一些优化,这就是syntr

浩浩的代码花园 478

java解决策略膨胀_java-锁膨胀的过程

先来看个奇怪的demopublic classA {int i=0;//boolean flag =false;public synchronized voidparse(){i++;JOLExample6.countDownLatch.countDown();}}睡眠5秒,测试public classJOLExample3 {staticA a;public static void main(S...

weixin_29840657的博客 227

【JAVA核心知识】20:synchronized实现原理与锁膨胀:无锁or偏向锁-轻量级锁-重量级锁,看完就懂

synchronized前言JDK对Synchronize的优化-锁膨胀偏向锁轻量级锁重量级锁重量级锁模式下的SynchronizeSynchronize 的核心组件Synchronized 的流程Synchronized 的实现Synchronized 的作用范围synchronized的简单使用 前言 Synchronized是通过对象内部的monitor(监视器锁)来实现的。monitor本质上又是依赖于底层操作系统的Mutex Lock来实现的,操作系统实现线程之间的切换 依赖于操作系统 Mutex

积 1806

synchronized锁的膨胀过程

在jdk1.6以前,随着并发数提高,synchronized吞吐量下降严重,而ReentrantLock则比较稳定,如果说ReentrantLock性能较强,那么synchronizedzeyuo

γìńɡ雄尐年ぐ的博客 941

JAVA锁优化和膨胀过程

HotSpot虚拟机开发团队在这个版本上花费了大量的精力去实现各种锁优化技术,如适应性自旋(Adaptive Spinning)、锁削除(Lock Elimination)、锁膨胀(Loc...

大数据星球-浪尖 153

Java-- synchronized--原理总结--重量级锁-轻量级锁和锁膨胀

Java-- synchronized--学习原理总结monitor(重量级锁)轻量级锁加锁和解锁锁膨胀 monitor(重量级锁) synchronized 关键字在使用的时候,往往需要指定一个对象与之关联,例如 synchronized(this),或者 synchronized(obj),synchronized 如果修饰的是实例方法,那么其关联的对象实际上是 this,如果修饰的是类方法,那么其关联的对象是 this.class。总之,synchronzied 需要关联一个对象,而这个对象就是 mo

qq_43539962的博客 275

锁底层实现及锁膨胀

Java锁底层实现及锁膨胀背景堆内存java内存模型缓存Synchronized原理Synchronized锁升级过程锁优化锁消除锁粗化二级目录三级目录 背景 堆内存 jvm中,对象在内存中的布局分为三块: 对象头:存储对象的哈市Code或锁信息,对象类型数据的指针和数组的长度等。 实例变量:存放类的属性数据信息,包括父类的属性信息,如果是数组的实例部分还包括数组的长度,这部分内存按4字节对齐。 填充数据:由于虚拟机要求对象起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅是为了字节对齐。

weixin_43489232的博客 154
上一篇: MySQL(七)存储过程
下一篇: Hystrix的使用,服务降级,服务熔断原理。。。
Dim_Jerry
博客等级 码龄8年 14粉丝 50原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值