本文共 5235 字,大约阅读时间需要 17 分钟。
悲观锁的问题:总是需要竞争锁,进而导致发生线程切换,挂起其他线程;所以性能不高。
乐观锁的问题:并不总是能处理所有问题,所以会引入一定的系统复杂度。
自旋锁的效率更高, 但是会浪费一些CPU资源 (自旋相当于CPU在那空转)
实现公平锁就需要付出一些额外的代价 所以公平锁的效率是略低于非公平锁的
可重入锁这就像是大门的三保险锁一样 我锁一层再锁一层 这种并不会造成我们死锁住自己 因为当我们想出去的时候又可以一层一层的开锁
- 一个线程一把锁 连续加锁俩次才 (保证使用的不是可重入锁)
- 俩个线程, 俩把锁, 相互获取对方的锁
- n个线程, n把锁, 哲学家就餐问题
1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用
2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。 3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。 4、循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。
我们假设内存中的原数据val,旧的预期值new,需要修改的新值tmp。
- 比较 new 与 val 是否相等。(比较)
- 如果比较相等,将 tmp 写入 val。(交换)
- 返回操作是否成功。
import java.util.concurrent.atomic.AtomicInteger;/** * Created with IntelliJ IDEA. * Description: If you don't work hard, you will a loser. * User: Listen-Y. * Date: 2020-08-04 * Time: 20:40 */public class Demo2 { public static void main(String[] args) throws InterruptedException { AtomicInteger atomicInteger = new AtomicInteger(); Thread thread = new Thread() { @Override public void run() { for (int i = 0; i < 5000; i++) { atomicInteger.addAndGet(1); } } }; Thread thread1 = new Thread() { @Override public void run() { for (int i = 0; i < 5000; i++) { atomicInteger.addAndGet(1); } } }; thread.start(); thread1.start(); thread.join(); thread1.join(); System.out.println(atomicInteger.get()); }}
/** * Created with IntelliJ IDEA. * Description: If you don't work hard, you will a loser. * User: Listen-Y. * Date: 2020-08-04 * Time: 20:53 */public class Demo3 { private static int count = 0; public static void main(String[] args) throws InterruptedException { Thread thread = new Thread() { @Override public void run() { for (int i = 0; i < 5000; i++) { count++; } } }; Thread thread1 = new Thread() { @Override public void run() { for (int i = 0; i < 5000; i++) { count++; } } }; thread.start(); thread1.start(); thread.join(); thread1.join(); System.out.println(count); }}
编辑器和JVM配合进行的
/** * Created with IntelliJ IDEA. * Description: If you don't work hard, you will a loser. * User: Listen-Y. * Date: 2020-08-04 * Time: 21:21 */public class Demo4 { public static void main(String[] args) { StringBuffer buffer = new StringBuffer(); buffer.append("listen"); buffer.append("listen"); buffer.append("listen"); buffer.append("listen"); System.out.println(buffer); }}
当有很多线程竞争锁的时候, 偏向锁状态被消除 此时没有得到锁的线程并不会直接直接挂起放弃 而是使用自旋锁 的方式来尝试去再次获取锁
自旋锁能保证让其他想竞争锁的线程尽快得到锁 但是也相应付出了一定的cpu资源
还是上面我去球馆打球的例子 如果此时就一个人来和我竞争这个篮球 我不会立马放弃 而是会稍微等会 看我是不是快回家了
没有上锁就是无所状态, 在使用syn上锁的时候, 没有发生竞争就是偏向锁, 如果有少数线程发生了竞争就使用cas乐观乐观的自旋锁不断的在访问获取锁状态也就是轻量级锁,当线程访问到达十次还不能获得锁就会进入重量级锁
转载地址:http://cjsci.baihongyu.com/