synchronized加锁
1.使用场景:共享变量改变。
2.作用:对象头加锁,同一个对象加锁同步互斥。
3.原理:
4.JVM锁优化:
Lock体系
一、锁策略(设计思想)
乐观锁: 假设认为数据一般情况下不会产生并发冲突,所以在数据进行提交更新的时候,才会正式对数据是否产生并发冲突进行检测,如果发现并发冲突了,则让返回用户错误的信息,让用户决定如何去做。并不总是能处理所有问题,所以会引入一定的系统复杂度。
同一时间点,经常只有一个线程操作共享变量,适合乐观锁
悲观锁: 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。总是需要竞争锁,进而导致发生线程切换,挂起其他线程;所以性能不高。
同一时间点,经常有多个线程操作共享变量,适合悲观锁
读写锁: 一个读写锁同时只能有一个写者或多个读者(与CPU数相关),但不能同时既有读者又有写者。
锁有两种形态:读锁和写锁
1.当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞
2.当读写锁在读加锁状态时,所有试图以读模式对它进行加锁的线程都可以得到访问权,但是以写模式对它进行加锁的线程将会被阻塞
3.当读写锁在读模式的锁状态时,如果有另外的线程试图以写模式加锁,读写锁通常会阻塞随后的读模式锁的请求,这样可以避免读模式锁长期占用,而等待的写模式锁请求则长期阻塞。
自旋锁: 没有自旋锁的情况下,抢锁失败,就立即放弃CPU,移至同步队列继续抢锁。随着多核CPU的出现,锁的线程很可能在其他核上运行着,一直在等当前锁的释放,一个锁的持有时间一般都比较短,虽然现在没抢到,很有可能在几个时钟周期后就抢到了。
公平锁 VS 不公平锁 &