Java 21个锁的概念

今天逛知乎看到一个不错的文章,文章的标题其实不太贴切,其实并不是按同一分类方法有21种锁,而是按不同方法分类的。不过以前从没想过竟然有这么多锁的概念:)

先帖地址:https://zhuanlan.zhihu.com/p/215271906

以下是一些总结和理解,有些关键或自己理解深的照抄原文:)

悲观 vs 乐观

悲观锁是通常意义上的锁,无论读写均锁定,一致性得到保证。如:Synchronized;

乐观锁则认为读多写少,读写冲突概率低,所以读时不锁,仅写时锁。乐观锁在更新前会把目标值与期望值做比较,仅当一致时更新(锁定)。如:CAS。

自旋

自旋只一种锁的等待方案。一般的线程当遇到资源已经被锁定时,直接切换线程环境,把CPU资源交给其它线程。而自旋则是线程空转,等待资源释放。适用于:1)多核(线程)结构CPU,单核显然是不适用的;2)资源使用时间短,快速释放的场合。

自旋锁,有一个自旋次数配置(-XX:PreBlockSpin),当超过特定的次数,线程仍未等到资源释放,则切换线程资源。JVM默认为10,可配置。同时,可配置为自适应自旋,根据上次旋转的次数等参数来动态调整这个次数。

CAS使用自旋锁。

可重入锁

可重入锁表示同一线程可以多次获取同一锁。如:ReentrantLock,Synchronized是可重入的。

读写锁

读写分离锁;读锁定时允许多线程读,一旦写锁定,则与悲观锁相同(不可再获取读锁)。

公平锁VS非公平锁

公平锁,线程请求某个资源时如遇到锁,则会进行排除,按FIFO的顺序依次获取资源;非公平锁:没有队列,谁先获得锁是不一定的。

非公平锁效率更高,但可能导致某些线程始终不能得到锁(线程饥饿)。synchronized是非公平锁,ReentrantLock通过构造函数指定该锁是公平的还是非公平的,默认是非公平的。

共享锁

用ReentrantReadWriteLock实现,其实就是乐观锁,读写锁的意思。

独占锁/互斥锁/同步锁===悲观锁

与悲观锁,互斥锁同义,即同一时刻只有一个线程能获取资源。synchronized,ReentrantLock

重量级 VS 轻量级锁

通过锁的实现方式区分锁的类型。

synchronized是通过对象内部的一个叫做监视器锁(monitor)来实现的,监视器锁本身依赖底层的操作系统的 Mutex Lock来实现。操作系统实现线程的切换需要从用户态切换到核心态,成本非常高。这种依赖于操作系统 Mutex Lock来实现的锁称为重量级锁。为了优化synchonized,引入了轻量级锁偏向锁

轻量级锁是JDK6时加入的一种锁优化机制: 轻量级锁是在无竞争的情况下使用CAS操作去消除同步使用的互斥量。轻量级是相对于使用操作系统互斥量来实现的重量级锁而言的。轻量级锁在没有多线程竞争的前提下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗。如果出现两条以上的线程争用同一个锁的情况,那轻量级锁将不会有效,必须膨胀为重量级锁。出现此情形时,轻量级锁性能要差于重量级锁。

偏向锁,则是轻量级锁的进一步优化,如果资源没有竞争,且总是倾向于使用同一个线程处理,则可以使用偏向锁。偏向锁会连CAS也忽略掉。

分段锁

一次不把所有资源都锁定,类似库库的页面级和行级锁这样的。文中以ConcurrentHashMap为例,ConcurrentHashMap里面包含了多个(默认16)个HashMap,每一个HashMap就是一个segment,在锁定时先计算出KEY,确定属于哪个segment,然后只锁定这个segment,提高并发效率。

死锁:不用解释

锁粗化

如果一段连续代码中有几处需要锁定同一资源,没必要反复加锁,解锁,在增加开销的同时还增加了竞争的可能性,将锁定放到更大的范围(代码段),即为锁粗化,是一种锁优化技术。

锁消除

如果通过技术手段可以不用加锁,称之为锁消除,也是一种锁优化技术。

synchronized——Java关键字

关键字,独占(互斥,悲观)锁,可重入锁,非公平锁。

作用于实例方法时,锁定一个对象;作用于静态方法时,锁定Class类,相当于全局锁。

作用于一个非null的对象实例时,锁定所有以该对象为锁的代码块。

Lock——Java接口

Java中的接口,属于可重入,悲观(独占,互斥,同步)锁。

需要手动获取和释放,而synchronized是完全自动的(锁定相当的代码段)

synchronized出现异常时,自动释放当前线程锁,不会导致死锁;而lock发生异常需要捕获并手动释放锁(unLock),因此建议在finally块中释放锁。

lock可以让等待线程响应中断,而synchornized会一直等待。

lock可以知道是否获取成功锁,而synchronized则不行。

lock可通过读写锁,实现共享锁,提高效率。

ReentrantLock——Lock的实现类

ReentrantLock是一个类,继承了lock接口,是可重入,悲观锁(同步,互斥,独占)。

ReentrantLock可以实现公平与非公平锁,而synchornized则只能是非公平锁。

ReentrantLock可通过Condition绑定多个条件。

Continue Reading

OSX外接机械键盘配置

最近入手了一个GS87D,摸索了一下配置。

GS87D的键盘布局与magic keyboard不太一样,最大的问题是底部的Modifier键布局不同。MagicKeyboard和内置键盘空格左侧都是FN,Ctrl,Option,Command右侧是 Command,Option。而87D则左边只有3个按键,右边则有4个,其中第2个是键盘的FN键不可重新映射的。

为了不和MAC键盘上的FN键冲突,以下GS87D键盘内置的FN键(空格右侧第二健)用FNX代替。

先尝试了键盘内置的切换ALT/WIN位置的快捷键(FNX+ALT),这样键位变成了:

Ctrl,Option,Command,Space,Option,FNX,Application(右键菜单),Ctrl。

这样看起来很恶心,首先是左右不对称,然后是没有了FN键,很多OSX上的操作都不能用了,为了解决这个问题,找到了一个相当不错的软件:Karabiner-Elements,这玩意可以映射键盘按键,并且是开源的。

先安装,有两个Application,一个是配置用的将常驻内存;一个是EventViewer。这个应用最常用的功能应该就是可以测试一下你按下的是哪个按键。

装完后我的配置如下:

这样的话,底部功能键就变成了:

Ctrl ,Option,Command,Space,Command,FNX,Option,FN。

这样一来相对内置键盘就有两个区别:

  1. FN从最左侧移动到最右侧。
  2. 右Command和右Option之间多了一个FNX键。

这两个问题都是键盘布局造成的,无法解决。

在安装步骤中有一个问题困扰了我很久,并导致内置键盘的功能键+Touchbar上虚拟按键的组合键完全失效,例如:Command+ESC,Ctrl+F4这样的都不能用。解决办法是:

  1. 在配置程序的设备页面中同时勾选No product name和Apple Internal Keyboard这两个设备(前面的勾即可),他们的VenderID应该相同,都是1452。
  2. 在配置程序的功能键页面,勾选Use all F1,F2…为标准功能键。

还有问题,如果你将键盘关机再开机,那么键位将恢复到Ctrl,Win,Alt的顺序;又要再按一次FNX+ALT来切换两个键位的位置,所以我后面干脆把左侧的两个按键也用Karabiner来重新映射而不是使用键盘内置的切换功能,一劳永逸。上图中已经体现了这个配置结果。

Continue Reading

给ESXi应用阿里云证书

网上有很多教程如何给ESXi使用自己的证书,我折腾了一回还把ESXi搞瘫了几天,记录一下供各位参考,免得你们跳进同一个坑。

这里有一个Windows下比较完整的教程,我的主要操作步骤也是参考这个的:

https://koolshare.cn/thread-137269-1-1.html

 

Step 1:购买域名并购买阿里云证书

略,这个不知道也没必要折腾这个了。

 

Step 2:生成CSR文件,这一步就是坑关键

生成CSR文件的openssl命令,注意参数:

openssl req -new -nodes -out rui.csr -keyout rui-orig.key -config openssl.cfg

根据这个教程是需要在windows下下载openssl,其实在OSX下本身就支持这个命令,关键是openssl.cfg文件,其实也是不需要的,openssl支持在命令行提示中输入(完成)配置。

后面回头看这个命令,其实也非常好理解-keyout rui-orig.key,这个参数的意思是:生成一个key文件,而我则是在参考了这个文章中的内容后,按如下顺序执行的:

https://yq.aliyun.com/articles/47314

命令1:openssl genrsa -out some.key 2048

命令2:openssl req -new -key some.key -out some.csr

这两个命令一个生成.key文件,一个生成.csr文件。第2个命令会提示你输入相关信息(比如:CN/HN/CS等,注意common name必须是你的域名,其它包括邮箱密码都可保持为空)

生成的.key文件最后需要上传到ESXi上,而csr文件则用于申请证书。

注意在windows版的教程中还有一个命令是

openssl rsa -in rui-orig.key -out rui.key

如果按我的两个命令的方法执行则不需要再执行这个转换的命令,因为用openssl genrsa本来生成的就已经是RSA的私钥。

在没有解决这个问题之前,我先通过搜索找到这样一篇文章,可以通过keychain生成csr但很遗憾我没有找到方法得到.key文件,所以就卡在这了。

https://www.jianshu.com/p/f20caf82938d

而我最大的特点是勇于折腾,在没有key文件的情况下,覆盖了crt文件并重启了ESXi,然后就没有WebUI了,解决的方法后面讲。

 

Step 3:用生成的csr文件生成证书

这个与前面的windows教程完成一致,只强调一个:申请证书时填的域名必须与CSR文件中的common name中的域名完全一致。

Step 4:下载并替换证书

从阿里云下载签发域名的Nginx版证书,后缀应是pem格式,假设这个文件为A

之前生成的some.key文件,假设这个文件为B。

通过SSH登录到ESXi,进入目录/etc/vmware/ssl目录,备份(我理解其实删除也完全没问题)rui.crt/rui.key这两个文件。

然后,通过vi命令创建新的rui.crt/rui.key这两个文件并保存,内容是:

A-> rui.crt

B->rui.key

 

Step 5:重启Management Agent

不知道命令行怎么重启,我正好连在console上,用键盘重启的,没有连接console的话直接重启ESXi效果也一样。

前面生成csr的时候因为没有生成正确的key文件,所以出现了一个非常严重的问题就是Management Agent(WebUI)连接不上了,但SSH正常。

解决的方法非常简单(需通过SSH连接):

1)备份后移除/etc/vmware/ssl下的rui.crt/rui.key这两个文件

2)执行/sbin/generate-certificates命令重新生成证书

3)重启Management Agents

 

操作完成后,可通过域名直接访问ESXi,Chrome不会提示证书异常,同时也可以保存密码了,对我等强迫症来说是个好事。

 

Continue Reading

推荐一款OSX下的截屏软件SnipPaste

一直想要一款心目中理想的截图软件:

1. 简洁快速

不要有乱七八糟的功能,加载和使用的速度快。

2. 支持截图后的标注操作,功能够用就行。

支持画框,箭头,文字,涂抹(马赛克)基本上就够用了。

3. 支持通过快捷键保存到剪贴板和文件

有两种比较常用的模式:

一)截图后立刻编辑(标注)然后保存(可通过快捷键选择进剪贴板或文件),一般截图都是这个情况。

二)截图后不需要编辑直接进剪贴板或文件。大量截图不需要标注的,这种情况比较少见,而且如果标注窗口支持快捷键的话对操作影响也很小,所以其实只需要完美的支持模式一即可。

前面用过的软件很多,主要是系统自带+SNIP。

SNIP其实也非常不错,前面我也推荐过,后面为什么改用系统的我不记得了。最近在大白软件站看到了截图软件推荐的SnipPaste就用一下试试,发现也非常不错。

 

UntitledImage

软件支持win/osx,目前osx仍是beta,官网上也没有截图。

优点:

1. 功能简洁但足够的强大;

2. 上面所有的需求都支持,同时还支持取色,这一点很好;

3. 支持多种快捷键保存方式,模式一和二都能比较好的支持。

4. 有一个很好用的paste功能:当你想要“标注”一个已经存在的图片时,从系统里复制然后paste就可以编辑了。

5. 支持很多有特色的选择操作(按像素调整选择区域)

缺点:

1. 先说最大的缺点:不支持长页面的截图,这一点确实是很大的问题,但已列入更新计划。XNIP就支持,但免费版有水印。

2. 标注界面比xnip少一个很常用的自动编号数字的功能。写操作手册时很需要。

3. 标注段选择保存为文件支持两个模式:手工保存(cmd+S)和快速保存(cmd+shift+s),前者快捷键简单但需要用户确认一次文件名,而快速保存则可以取消。建议交换这两个快捷键。不过支持另外一个快捷操作的配置:Enter/鼠标双击/中键双击的默认操作配置。可以把Enter配置成进剪贴板,双击快速保存。

4. 之前以为不支持选择控件,其实是需要开启一个配置项。

 

总结一下:

XNIP与SnipPaste我觉得都挺不错,关键功能上Xnip支持Scroll截图占优;但细节功能上后者明显更为强大。Xnip的高级功能收费(Scroll免费版有水印),SnipPaste细节功能较多且适合喜欢键盘操作的开发人员使用。SnipPaset能够快点支持Scrollfalr话就可以抛弃Xnip了,如果能够支持前面的标注自动增长序列更好。

话说我现在的截图用的是系统自带的,我完全不记得为什么放弃XNIP了:)因为不支持对TouchBar截图?

 

Continue Reading

迁移gitea遇到的remote rejected的问题

备案域名之后,把git服务从原来的aws免费主机搬回了国内,同时修改了域名指向,恢复了gitea服务之后,有同事反映说commit失败:

Snipaste 2020 02 08 00 05 50

一般的说法是权限问题,但是整个恢复(迁移)过程并未对gitea的用户权限做修改,而用管理员账号做过新的repo的commit操作均是正常的,后面在gitea@github找到答案:

https://github.com/go-gitea/gitea/issues/2270

UntitledImage

登录gitea后台,dashboard执行一下(Resynchronize pre-receive, update and post-receive hooks of all repositories.)搞定。

UntitledImage

Continue Reading

阿里云DDNS重复A记录问题

前面提到使用了阿里云的动态DDNS,发现域名解析中出现了多个A记录,一开始以为会自动失效(过期),后来发现不是,于是又开始了折腾:

1. 用的是Padavan固件所带的脚本功能;界面上没怎么仔细写逻辑需求,链接里也没仔细的写要求,只写了需要几个KEY,这个当然是正确的(不然A记录也没办法新增),于是通过SSH登录进去,终于在/etc/storage/script下找到了Sh42_aliddns.sh文件;

2. 读完脚本大概确定逻辑,脚本会先通过API获取所有的域名记录,并尝试获取recordid;如果获取成功则updateRecord,反之则addRecord,显然问题出现在:)

3. 脚本是通过“query_recordid | get_recordid”两个函数获取返回值,前一个是通过API获取域名解析记录,后一个是从中解析出相应域名的recordid,所以也不能判断到底是返回值错误还是解析结果出现了问题,于是写了一test函数,加到脚本中:sh Sh42_aliddns.sh test测试query_recordid的结果,错误提示非常明确:“”Code”:”Forbidden.RAM”,”Message”:”User: not authorized to operate on the specified resource, or this API doesn’t support RAM.”。 看起来不像是这个API不支持RAM的原因(连ADD都支持没道理Query不支持的)。

4. 查看阿里云的授权配置:)感觉没有异常,如下:

{
    "Version": "1",
    "Statement": [
        {
            "Action": [
                "alidns:AddDomainRecord",
                "alidns:DescribeDomainRecords",
                "alidns:UpdateDomainRecord"
            ],
            "Resource": "acs:alidns:*:*:domain/brallow.cn",
            "Effect": "Allow"
        }
    ]
}

问题其实就出现在这里,因为这个策略是我从网上抄来的,并没有仔细研究alidns有什么Action列表,实际上alidns:DescribeDomainRecords与alidns:DescribeSubDomainRecords是两个不同的Action,而脚本使用的是后者,我并没有授权这个独立的RAM访问,新增授权,问题解决。

Continue Reading

折腾SSL证书

备案了brallow.cn,又申请了阿里的免费证书,并应用了阿里的动态域名,把家里的NAS导入了新的证书:

记录几个常用的东西:
1. 用下载的证书,apache版,key是私钥;public.crt是公钥;chain.crt不知道干嘛用的,导入即可。

2. 不可应用DSM中的”自定义域名“设置,否则通过该域名访问DSM时将出现Synology的404页面;如果出现这一问题,使用IP或其它域名访问即可。

3. 应用配置后注意将该证书修改为默认证书,并将相关服务通过配置修改为新的证书(默认将使用自动生成的证书)。

可能是我的DSM的原因,开启https并应用设置重新启动web server之后并不能通过https访问,重启以后解决了。

其实我的本意是要把ESXi应用证书的,(不知道是不是这个原因,没有有效证书的情况下Chrome不能记录(保存)密码)但操作步骤太复杂了,打算放弃。

Continue Reading

ESXi异常关机,虚拟机报Failed – Object type requires hosted I/O

本来是在通过HAAS折腾DC1插座的,结果不知道为什么突然插座就断电了。

解决方法很简单,两个命令:

  1. vmkfstools -x check ./hassos_ova-3.7.vmdk,其中vmdk中待检查的磁盘文件名。
  2. ESXi会返回提示该磁盘是否需要修复,如果需要执行下一步。
  3. vmkfstools -x repair ./hassos_ova-3.7.vmdk,ESXi返回修复结果。
  4. 重启虚拟机:)
Continue Reading

2020……

祝大家新年快乐!

Happy New Year!

今年的第一个开发任务,居然会是MFC……上一次用MFC做开发应该有快20年了吧,还是MFC4 ……Lj4OrMore:)可惜的是我居然连源代码都找不到了。

Continue Reading
1 2 3 12