包教包会Cas无锁机制-手写无锁机制Lock锁

1.现在有这么一个问题10个线程对一个全局变量进行赋值就是i++嘛 每个线程赋值1000次 最后打印结果是几

  结果是10*1000等于一万对吗?下面是代码测试。

package com.hd.jxd;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class DemoLock {
   int i=0;
    public void incr(){
             i++;
    }

    public static void main(String[] args) {
        DemoLock demoLock=new DemoLock();
        for (int i = 0; i <10 ; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < 1000; j++) {
                        demoLock.incr();
                    }
                }
            }).start();
        }

        try {
            Thread.sleep(1000);//休息一下等待线程全部执行完在打印不然会执行完一半就没有意思了
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(demoLock.i);
    }


}
代码给你们写好了直接复制粘贴测试一下打印结果为8641是一个小于一万的数(每次测试不一定是这个结果,但是一定小于一万)

原因是当其中一个线程在内存中拿到结果,对其进行赋值的时候其实其他线程已经在内存中把他修改了,就好比一个小姐姐要嫁妆说好10万块钱,谁出的高嫁给谁,当你准备好11万的时候,人家土豪已经把11万给他它了,更欺负人的是你过来开的时候小姐姐都已经是12万了,(小姐姐代表内存)。

如果想再深入解请看CAS无锁机制必须了解的JVM内存模型这篇文章下边是链接绝对收获满满

https://blog.csdn.net/weixin_39831786/article/details/88379024

这怎么办你可以加synchronized关键字给他加锁,但是我们现在不用这种方法,用一种无锁机制来解决,首先说你加synchronized代表什么,还是拿刚才那个例子举例,你说好10万嫁妆娶人家小姐姐,但是你害怕再有土豪捣乱,你直接把小姐姐锁在一个屋子里与外界隔绝谁都不见,直到你把10万拿来美滋滋的娶人家。这样首先会丧失效率,对人家小姐姐也不公平。

那怎么办,我们用一个Lock锁解决看下边代码

package com.hd.jxd;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public  class DemoLock {
   int i=0;

    Lock lock=new ReentrantLock();
    
    public  void incr(){

        lock.lock();//上锁

         try {
             i++;
         }finally {
             lock.unlock();//解锁
         }

    }

    public static void main(String[] args) {
        DemoLock demoLock=new DemoLock();
        for (int i = 0; i <10 ; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int j = 0; j < 1000; j++) {
                        demoLock.incr();
                    }
                }
            }).start();
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(demoLock.i);
    }


}
打印结果为1万 看了嘛,代码给你们写好直接粘贴试一下
Lock lock=new ReentrantLock();
lock.lock();
lock.unlock();
就加了这三行完美解决,效率完全碾压synchronized

我说一下原理,它是一种Cas无锁机制,java通过一个unsafe类直接访问内存,然后在内存中拿到值进行比较,如果发现不对,先改正之后进行赋值,‘

还是拿刚才那个例子。小姐姐和你说好了10万块钱,因为有土豪的捣乱不断被修改,那怎么办,你学精了我在找小姐姐送嫁妆的时候我先问一下,你现在多少钱嫁人了,(小姐姐代表内存)他说11万了,你说卧槽好吧我改11万然后加一万12万给你行了吧。看源码:

 

这个valueOffset就是通过unSafe类直接访问内存拿到小姐姐现在的报价,except是你期望的值本来是说好10万+1是11万

但是小姐姐现在报价就是11万卧槽,怎么办,update直接改成12万吧不然没法结婚啊。

重点了来,为了让大加更能了解Lock锁的原理我直接手写一个Lock锁,一样能娶到小姐姐。

我放到下期

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值