轻量级

Java锁的升级策略 偏向锁 轻量级锁 重量级锁

匿名 (未验证) 提交于 2019-12-02 21:40:30
这三种锁是指锁的状态,并且是专门针对Synchronized关键字。JDK 1.6 为了减少"重量级锁"的性能消耗,引入了“偏向锁”和“轻量级锁”,锁一共拥有4种状态:无锁状态、偏向锁、轻量级锁、重量级锁。锁状态是通过对象头的Mark Word来进行标记的: 锁可以升级但不能降级,意味着偏向锁升级成轻量级锁后不能降级成偏向锁,这种锁升级却不能降级的策略,是为了提高获得锁和释放锁的效率 重量级锁:依赖于底层操作系统的Mutex Lock,线程会被阻塞住 缺点:加锁和解锁需要从用户态切换到内核态,性能消耗较大 轻量级锁:基于重量级锁进行了优化(避免上下文切换,提高了性能),它假设多线程竞争是互相错开的,不会发生线程阻塞,呢么上下文切换就是多余的 第一个特点:采用了CAS操作加锁和解锁,由于轻量级锁的锁记录(Lock Record)是存放在对象头和线程空间里的,因此加锁和解锁不需要上下文切换,性能消耗较小 第二个特点:一旦发生多线程竞争,首先基于“自旋锁”思想,自旋CPU循环等待一段时间,不会发生上下文切换,如果还是无法获得锁,就将锁升级为重量级锁 偏向锁:基于轻量级锁进行了优化(减少多次的加锁和解锁,提高了性能),它假设整个过程只有一个线程获得锁,呢么多次的加锁和解锁就是多余的 特点:在第一次获得锁之后不会释放锁,它会一直持有锁,后续进入锁时只需检查一下锁状态和偏向线程ID是否为自己

Web轻量级框架Gin-中间件使用

两盒软妹~` 提交于 2019-12-02 17:59:37
Gin的中间件是Gin框架中一个极其重要的内容,而且Gin中间件也是使用Gin框架开发一个完整Web程序时不可或缺的部分,所以有必要好了解一下。 什么是Gin中间件 Gin中间件是什么?Gin中间件的作用是什么?要怎么样使用中间件呢? 1. Gin中间件的作用 好吧,简单来说,Gin中间件的作用有两个: Web请求到到达我们定义的HTTP请求处理方法之前,拦截请求并进行相应处理(比如:权限验证,数据过滤等),这个可以类比为 前置拦截器或前置过滤器 在我们处理完成请求并响应客户端时,拦截响应并进行相应的处理(比如:添加统一响应部头或数据格式等),这可以类型为 后置拦截器或后置过滤器 2. Gin中间件的定义 在Gin框架中,中间件的类型定义如下代码所示,可以看出,中间件实际上就是一个以gin.Context为形参的函数而已,与我们定义处理HTTP请求的Handler本质上是一样的,并没有什么神秘可言。 type HandlerFunc func(*Context) 3. Gin内置中间件 在使用Gin框架开发Web应用时,常常需要自定义中间件,不过,Gin也内置一些中间件,我们可以直接使用,下面是内置中间件列表: func BasicAuth(accounts Accounts) HandlerFunc func BasicAuthForRealm(accounts Accounts

Web轻量级框架Gin-中间件使用

落爺英雄遲暮 提交于 2019-12-02 17:45:34
Gin的中间件是Gin框架中一个极其重要的内容,而且Gin中间件也是使用Gin框架开发一个完整Web程序时不可或缺的部分,所以有必要好了解一下。 什么是Gin中间件 Gin中间件是什么?Gin中间件的作用是什么?要怎么样使用中间件呢? 1. Gin中间件的作用 好吧,简单来说,Gin中间件的作用有两个: Web请求到到达我们定义的HTTP请求处理方法之前,拦截请求并进行相应处理(比如:权限验证,数据过滤等),这个可以类比为 前置拦截器或前置过滤器 在我们处理完成请求并响应客户端时,拦截响应并进行相应的处理(比如:添加统一响应部头或数据格式等),这可以类型为 后置拦截器或后置过滤器 2. Gin中间件的定义 在Gin框架中,中间件的类型定义如下代码所示,可以看出,中间件实际上就是一个以gin.Context为形参的函数而已,与我们定义处理HTTP请求的Handler本质上是一样的,并没有什么神秘可言。 type HandlerFunc func(*Context) 3. Gin内置中间件 在使用Gin框架开发Web应用时,常常需要自定义中间件,不过,Gin也内置一些中间件,我们可以直接使用,下面是内置中间件列表: func BasicAuth(accounts Accounts) HandlerFunc func BasicAuthForRealm(accounts Accounts

面试必问的Synchronized知道这些就可以了

♀尐吖头ヾ 提交于 2019-12-02 14:41:07
摘自: https://www.cnblogs.com/wyc1994666/p/11748212.html 面试必问的Synchronized知道这些就可以了 Synchronized关键字算是Java的元老级锁了,一开始它撑起了Java的同步任务,其用法简单粗暴容易上手。但是有些与它相关的知识点还是需要我们开发者去深入掌握的。比如,我们都知道通过Synchronized锁来实现互斥功能,可以用在方法或者代码块上,那么不同用法都是怎么实现的,以及都经历了了哪些优化等等问题都需要我们扎实的理解。 1.基本用法 2.实现原理 2.1 同步代码块的实现 2.2 同步方法的实现 3.锁升级 3.1 Java对象头介绍 3.2 什么是锁升级 1.基本用法 通常我们可以把Synchronized用在一个方法或者代码块里,方法又有普通方法或者静态方法。 对于普通同步方法,锁是当前实例对象,也就是this public class TestSyn{ private int i=0; public synchronized void incr(){ i++; } } 对于静态同步方法,锁是Class对象 public class TestSyn{ private static int i=0; public static synchronized void incr(){ i++; } }

Synchronized实现原理(一)

♀尐吖头ヾ 提交于 2019-12-01 22:09:15
无锁,偏向锁,轻量级锁 ,重量级锁 偏向锁:对象头存储线程ID,可重入(根据线程ID判断) 轻量级锁:复制对象头到Lock Record 记录锁信息,拥有锁 复制的Lock Rrecord 指向对象头 重量级锁:mointer监控 来源: https://www.cnblogs.com/fanBlog/p/11323407.html

CAS原理 Java SE1.6中的Synchronized

Deadly 提交于 2019-12-01 20:24:50
在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁(后面的章节还会谈到锁)。 锁机制存在以下问题: (1)在多线程竞争下,加锁、释放锁会导致比较多的上下文切换和调度延时,引起性能问题。 (2)一个线程持有锁会导致其它所有需要此锁的线程挂起。 (3)如果一个优先级高的线程等待一个优先级低的线程释放锁会导致优先级倒置,引起性能风险。 volatile是不错的机制,但是volatile不能保证原子性。因此对于同步最终还是要回到锁机制上来。 独占锁是一种悲观锁,synchronized就是一种独占锁 ,会导致其它所有需要锁的线程挂起,等待持有锁的线程释放锁。而另一个更加有效的锁就是乐观锁。所谓 乐观锁就是, 每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。 CAS 操作 上面的乐观锁用到的机制就是CAS,Compare and Swap。 CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。 非阻塞算法 (nonblocking algorithms) 一个线程的失败或者挂起不应该影响其他线程的失败或挂起的算法。 现代的CPU提供了特殊的指令,可以自动更新共享数据,而且能够检测到其他线程的干扰,而 compareAndSet()

synchronized底层实现原理

不羁的心 提交于 2019-12-01 18:39:08
基于进入和退出管程(Monitor)对象实现,无论显式(Monitorenter Monitorexit)还是隐式都是如此。同步方法并不是由monitorenter和monitorexit指令来实现同步的,而是由方法调用指令读取运行时常量池中的ACC_SYNCHRONIZED标志来隐式实现的。 在JVM中,对象在内存中的布局分为三块区域:对象头、实例数据和对齐填充。 实例变量:存放类的属性数据信息,包括父类的属性信息,如果是数组的实例部分还包括数组的长度,这部分内存按4字节对齐。 填充数据:由于虚拟机要求对象起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅是为了字节对齐,这点了解即可 而对于顶部,则是Java头对象,它实现synchronized的锁对象的基础,这点我们重点分析它,一般而言,synchronized使用的锁对象是存储在Java对象头里的,jvm中采用2个字来存储对象头(如果对象是数组则会分配3个字,多出来的1个字记录的是数组长度),其主要结构是由Mark Word 和 Class Metadata Address 组成 虚拟机位数 头对象结构 说明 32/64bit Mark Word 存储对象的hashCode、锁信息或分代年龄或GC标志等信息 32/64bit Class Metadata Address 类型指针指向对象的类元数据

Java多线程之线程安全(0)Java内存区域与Java内存模型

自作多情 提交于 2019-12-01 15:25:05
概况 本文内容 1.Java内存区域划分 2.Java内存模型JMM 3.硬件内存架构与Java内存模型 4.Jvm中线程实现机制 5.线程安全问题的原因 一.理解Java内存区域与Java内存模型 看下图 1.1Java内存区域 各个区域的解释和功能 方法区(Method Area): 方法区属于线程 共享 的内存区域,又称Non-Heap(非堆),主要用于 存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码 等数据,根据Java 虚拟机规范的规定,当方法区无法满足内存分配需求时,将抛出OutOfMemoryError 异常。值得注意的是在方法区中存在一个叫 运行时常量池(Runtime Constant Pool)的区域,它主要用于存放编译器生成的各种字面量和符号引用 ,这些内容将在类加载后存放到运行时常量池中,以便后续使用。 JVM堆(Java Heap): Java 堆也是属于线程 共享 的内存区域,它在虚拟机启动时创建,是Java 虚拟机所管理的内存中最大的一块,主要用于存放对象实例, 几乎所有的对象实例都在这里分配内存 ,注意Java 堆是垃圾收集器管理的主要区域,因此很多时候也被称做 GC 堆 ,如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError 异常。 程序计数器(Program Counter

看完你就明白的锁系列之锁的状态

我是研究僧i 提交于 2019-12-01 11:56:35
前面两篇文章我介绍了一下 看完你就应该能明白的悲观锁和乐观锁 看完你就明白的锁系列之自旋锁 看完你就会知道,线程如果锁住了某个资源,致使其他线程无法访问的这种锁被称为悲观锁,相反,线程不锁住资源的锁被称为乐观锁,而自旋锁是基于 CAS 机制实现的,CAS又是乐观锁的一种实现,那么对于锁来说,多个线程同步访问某个资源的流程细节是否一样呢?换句话说,在多线程同步访问某个资源时,锁的状态会如何变化呢?本篇文章来探讨一下。 锁状态的分类 Java 语言专门针对 synchronized 关键字设置了四种状态,它们分别是: 无锁、偏向锁、轻量级锁和重量级锁 ,但是在了解这些锁之前还需要先了解一下 Java 对象头和 Monitor。 Java 对象头 我们知道 synchronized 是悲观锁,在操作同步之前需要给资源加锁,这把锁就是对象头里面的,而Java 对象头又是什么呢?我们以 Hotspot 虚拟机为例,Hopspot 对象头主要包括两部分数据: Mark Word(标记字段) 和 Klass Pointer(类型指针) 。 Mark Word :默认存储对象的HashCode,分代年龄和锁标志位信息。这些信息都是与对象自身定义无关的数据,所以Mark Word被设计成一个非固定的数据结构以便在极小的空间内存存储尽量多的数据。它会根据对象的状态复用自己的存储空间

看完你就明白的锁系列之锁的状态

佐手、 提交于 2019-12-01 11:54:16
前面两篇文章我介绍了一下 看完你就应该能明白的悲观锁和乐观锁 看完你就明白的锁系列之自旋锁 看完你就会知道,线程如果锁住了某个资源,致使其他线程无法访问的这种锁被称为悲观锁,相反,线程不锁住资源的锁被称为乐观锁,而自旋锁是基于 CAS 机制实现的,CAS又是乐观锁的一种实现,那么对于锁来说,多个线程同步访问某个资源的流程细节是否一样呢?换句话说,在多线程同步访问某个资源时,锁的状态会如何变化呢?本篇文章来探讨一下。 锁状态的分类 Java 语言专门针对 synchronized 关键字设置了四种状态,它们分别是: 无锁、偏向锁、轻量级锁和重量级锁 ,但是在了解这些锁之前还需要先了解一下 Java 对象头和 Monitor。 Java 对象头 我们知道 synchronized 是悲观锁,在操作同步之前需要给资源加锁,这把锁就是对象头里面的,而Java 对象头又是什么呢?我们以 Hotspot 虚拟机为例,Hopspot 对象头主要包括两部分数据: Mark Word(标记字段) 和 Klass Pointer(类型指针) 。 Mark Word :默认存储对象的HashCode,分代年龄和锁标志位信息。这些信息都是与对象自身定义无关的数据,所以Mark Word被设计成一个非固定的数据结构以便在极小的空间内存存储尽量多的数据。它会根据对象的状态复用自己的存储空间