CAS

深度探索JFR

泄露秘密 提交于 2020-04-06 03:54:57
Event 采集详细配置 目前,JDK 11 一共有136个 Event 采集配置。这里会比较详细的去看每一个Event,并说明基本应用,建议配置。如果 default.jfc 中没有打开或者需要修改的配置,会将配置文件代码发出来。 1. JFR 相关 Event 一共4个 Event,但是需要关心的就下面这两个 Data Loss :数局丢失 Event,当有数据发生丢失时,会有这个Event 进行记录。包括开始时间,Amount(本次丢失多少事件),Total(一共丢失多少事件) Recording Setting :记录详细配置采集 Event,会在每次产生新的 Data Chunk 的时候采集一次所有的 Event 的详细配置并记录到这个 Event 中。 这些在 default.jfc 中默认打开 2. JAVA 应用相关 2.1. TLAB 相关 众所周知,TLAB (Thread Local Allocation Buffer)目的是为类进行内存快速分配。堆内存所有线程共享访问,所以在堆内存上面分配对象,就会锁定整个堆,这样效率太低。TLAB 是位于堆内存上面的一块内存区域,在为每个线程分配 TLAB 的时候才会锁定堆(G1 是CAS分配)。分配对象的时候,优先从线程的 TLAB 上分配,这样就不用和其他线程同步。当对象比较大的时候,例如对于 G1 来说,

搞定SEO,看这一篇就够了

百般思念 提交于 2020-04-06 03:53:02
一、SEO入门 1、SEO是什么? SEO(Search Engine Optimization)中文意思为搜索引擎优化。在了解搜索引擎自然排名机制的基础上,对网站进行内部及外部的调整优化,改进网站在搜索引擎中的关键词自然排名,从而获得更多来自搜索引擎的流量。整个过程是不需要向搜索引擎服务商缴费的。 与SEO相对应的叫SEM(Search Engine Marketing),中文意思为搜索引擎营销,是在向搜索引擎服务商那里购买相应的关键词,从而获得排名提升的目的。 2、为什么要做SEO? 上面说到网站要想提高流量,需要考虑SEO或者SEM,但是相较之下,SEO有很多优点是SEM不具备的。 SEO的优点: 用户通过自然搜索访问到网站,信任感更高。老网民已经对于搜索引擎的广告位置具有免疫力,SEM的位置很多时候会被用户自动忽略 通过SEO获得的排名更持久,且成本低(无需向搜索引擎付费),SEM是付费停止后,由它带来的流量也就渐渐消失了 在通过SEO提高网站排名的过程,其实是网站修炼自身内功的过程,有助于长期改善用户体验 3、在公司里哪个岗位的人做SEO? SEO相关人员一般要从事以下工作: SEO负责人:负责网站SEO的策略以及方向 SEO执行:调整重要页面的Title、正文内容、关键词分布及格式、增加和调整Tags、调整内部连接等页面优化因素 工程师:对网站内部结构、分类设置

CAS

我与影子孤独终老i 提交于 2020-04-05 19:53:49
CAS: jdk1.5之前都是通过synchronized来实现同步的,这就导致有锁 锁机制问题: 1.多线程竞争下,加锁和释放锁,会导致比较多的上下文切换和调度延时,引起性能问题 2.一个线程持有锁会导致其他所有需要此锁的线程挂起 3.如果一个优先级高的线程等待一个优先级低的线程释放锁,会导致优先级倒置。 什么是CAS 概念:即比较再交换。 过程:最终调用native的CAS方法 效果:是在不加锁的状态下,在多线程访问时,保证线程数据一致性问题 ABA问题: 其他线程将值修改为A,再修改为B,然后再修改为A,解决方案,修改的值+版本号 原理: CAS最终是通过调用JNI的代码实现的,JNI:Java Native Interface java本地调用,允许Java调用其他语言 JNI调用c++的代码 C++调用CPU底层指令lock cmpxchg实现的。cas的原子性实际是cpu实现的 在jdk中的应用: jdk5增加了并发包java.util.concurrent.*,下面的类使用了CAS算法 缺点: ABA问题: 解决方案是在变量前面加上版本号,每次变量更新的时候把版本号加1,把A-B-A变成1A-2B-3A, jdk1.5中可以使用AtomicStampedReference解决 自旋循环开销时间大 只能保证一个共享变量的原子操作。 来源: oschina 链接:

并发处理笔记:使用并发工具类库,就安全了吗?

泄露秘密 提交于 2020-04-05 17:52:18
没有意识到线程重用导致用户信息错乱的bug 我们知道,ThreadLocal适用于变量在线程间隔离,而在方法和类间共享的场景. 如果信息获取比较昂贵(比如从数据库中查询用户信息),那么在ThreadLocal中缓存数据是比较合适的做法.那什么时候会出现用户信息错乱的bug呢? 来看一个例子,使用spring boot创建一个web应用程序,使用threadlocal存放一个integer的值表示用户id,最后输出两次获取的值和线程名称. private ThreadLocal<Integer> currentUser = ThreadLocal.withInitial(() -> null); @GetMapping("wrong") pubilc Map wrong(@RequestParam("userId") Integer userId) { String before = Thread.currentThread().getName() + ":" + currentUser.get(); currentUser.set(userId); String after = Thread.currentThread().getName() + ":" + currentUser.get(); Map result = new HashMap(); result.put(

给cas自定义login界面

喜你入骨 提交于 2020-04-01 00:29:55
2. 修改jsp登录页面 离线文件准备好后,就可以对CAS的jsp文件下手了。不过这里强烈建议不要在原有的文件上进行修改,最好建立一份新的theme。具体办法如下: (1)停掉Tomcat服务,进入“%TOMCAT_HOME%\webapps\cas\WEB-INF\view\jsp”文件夹,把default文件夹复制一份在本目录下,取名“custom”。 (2)进入“%TOMCAT_HOME%\webapps\cas\themes”文件夹,将default文件夹复制一份在本目录下,取名“custom”。 (3)进入“%TOMCAT_HOME%\webapps\cas\WEB-INF\classes”文件夹,将“default_views.properties”文件复制一份并重新命名为“custom_views.properties”。 (4)将离线登录页面中做好的“cas.css”文件拷贝到新建的“%TOMCAT_HOME%\webapps\cas\themes\custom”文件夹;将样式文件中用到的图片拷贝到“%TOMCAT_HOME%\webapps\cas\images”文件夹。(注意:css文件中引用图片的相对路径不要搞错。) (5)接下来是修改“%TOMCAT_HOME%\webapps\cas\WEB-INF\view\jsp\custom\ui

CAS -- ABA问题的解决方案

点点圈 提交于 2020-03-31 13:05:55
CAS:Compare and Swap, 翻译成比较并交换。 java.util.concurrent包中借助CAS实现了区别于synchronized同步锁的一种乐观锁。 其原理是CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。 我们现在来说什么是ABA问题。假设内存中有一个值为A的变量,存储在地址V中。 此时有三个线程想使用CAS的方式更新这个变量的值,每个线程的执行时间有略微偏差。线程1和线程2已经获取当前值,线程3还未获取当前值。 接下来,线程1先一步执行成功,把当前值成功从A更新为B;同时线程2因为某种原因???被阻塞住,没有做更新操作;线程3在线程1更新之后,获取了当前值B。 为什么线程3又反过来操作???是自旋吗??? 在之后,线程2仍然处于阻塞状态,线程3继续执行,成功把当前值从B更新成了A。 最后,线程2终于恢复了运行状态,由于阻塞之前已经获得了“当前值A”,并且经过compare检测,内存地址V中的实际值也是A,所以成功把变量值A更新成了B。 个人见解: 不是说一定出现ABA情况,是说有出现这种情况的可能性。也就是举一个特例来说明问题的可能性??? 看起来这个例子没啥问题,但如果结合实际,就可以发现它的问题所在。 我们假设一个提款机的例子。假设有一个遵循CAS原理的提款机

Java synchronized 关键字的实现原理

╄→尐↘猪︶ㄣ 提交于 2020-03-29 11:14:29
数据同步需要依赖锁,那锁的同步又依赖谁?synchronized给出的答案是在软件层面依赖JVM,而Lock给出的方案是在硬件层面依赖特殊的CPU指令,大家可能会进一步追问:JVM底层又是如何实现synchronized的? 本文所指说的JVM是指Hotspot的6u23版本,下面首先介绍synchronized的实现: synrhronized关键字简洁、清晰、语义明确,因此即使有了Lock接口,使用的还是非常广泛。其应用层的语义是可以把任何一个非null 对象 作为"锁",当synchronized作用在方法上时,锁住的便是对象实例(this);当作用在静态方法时锁住的便是对象对应的Class实例,因为 Class数据存在于永久带,因此静态方法锁相当于该类的一个全局锁;当synchronized作用于某一个对象实例时,锁住的便是对应的代码块。在 HotSpot JVM实现中,锁有个专门的名字:对象监视器。 1. 线程状态及状态转换 当多个线程同时请求某个对象监视器时,对象监视器会设置几种状态用来区分请求的线程: Contention List:所有请求锁的线程将被首先放置到该竞争队列 Entry List:Contention List中那些有资格成为候选人的线程被移到Entry List Wait Set:那些调用wait方法被阻塞的线程被放置到Wait Set OnDeck

并发编程相关面试题四

倖福魔咒の 提交于 2020-03-28 12:34:17
一、Java开发中用过哪些锁 1、乐观锁   乐观锁顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS(Compare and Swap 比较并交换)实现的   乐观锁适合读操作非常多的场景,不加锁会带来大量的性能提升;     乐观锁在Java中的使用,是无锁编程,常常采用的是CAS算法,典型的例子就是原子类,通过CAS自旋实现原子操作的更新。 2、悲观锁   悲观锁总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。比如Java里面的同步原语synchronized关键字的实现就是悲观锁。   悲观锁适合写操作非常多的场景;   悲观锁在Java中的使用,就是利用各种锁; 3、独享锁   独享锁是指该锁一次只能被一个线程所持有。   独享锁通过AQS来实现的,通过实现不同的方法,来实现独享锁。   对于Synchronized而言,当然是独享锁。 4、共享锁   共享锁是指该锁可被多个线程所持有。  

面试刷题15:synchronized底层是如何实现的?

若如初见. 提交于 2020-03-27 17:09:23
3 月,跳不动了?>>> <br />所有的同步场景都是基于锁。锁在并发编程中发挥重要作用。<br /> <br />我是李福春,我在准备面试,今天的题目是:<br /> <br /> <br /> synchronized底层是如何实现的? 答: synchronized是在底层的jvm中实现的,即c++写的,synchronized的实现是基于一对monitorenter, monitorexit指令实现的,monitor对象是同步的基本实现单元。<br /> <br />在java6中,monitor依靠操作系统提供的内部互斥锁,需要在用户态空间和内核态空间切换,所以同步操作是一个比较重的操作,开销比较大。<br /> <br />在java7之后,monitor有三种不同的实现,即偏斜锁,轻量级锁,重量级锁。<br /> <br />基于对象头的markword,标记上偏向的线程id, 在没有竞争的条件下,使用的是偏斜锁;<br />当有多个线程来竞争偏斜锁,基于cas对对象头的markword来进行竞争,如果拿到了,升级为轻量级锁。<br />没拿到则升级为重量级锁;<br /> <br />锁降级发生在jvm进入安全点检查的时候,对monitor进行降级。<br /> <br /> synchronized底层实现 <br />对象头结构:<br /> <br />

c++ atomic atomic_compare_exchange_weak CAS编程

别来无恙 提交于 2020-03-26 16:54:07
3 月,跳不动了?>>> 概述 在多线程应用中有个很典型的业务就是共同争抢一个某一个资源,比如很典型的秒杀,很多的线程在争夺某一个资源。本文以一个最简单的例子说明,2万个线程一起争夺一个变量+1的操作。 只使用atomic 在https://my.oschina.net/u/3707404/blog/3211668中,使用atomic类型可以避免多线程加锁导致的效率问题,同时保持资源安装,但是atomic本身有也其缺陷,其不能保证访问的一致性,即当100个线程都执行+1他能保证每一个线程的操作都会成功,但是如果你访问这个变量,其不保证每一个线程都看到的是最新的值,通过下面简单的代码你就会体会到。 #include <vector> #include <queue> #include <iostream> #include <boost/thread.hpp> #include <chrono> class Task { public : std :: atomic < int > queue ; boost :: mutex mutex ; Task () { queue = 0 ; } void get() { if ( queue == 0 ) { usleep( 1 ); queue ++ ; } } }; int main( int argc, char **argv) {