zoukankan      html  css  js  c++  java
  • java中常见的锁

    1.悲观锁

    • 认为别的线程都会修改数据,二话不说先锁上
    • synchronized

    2.乐观锁

    • 乐观豁达,起初不操作。最后修改的时候比对一下版本,不一致再上锁

    3.可重入锁

    • 外层锁了之后,内层仍可以直接使用

    4.不可重入锁

    • synchronized、ReentrantLock 重锁
    • 不可重入锁
    • 外层锁了之后,内层使用需要排队

    5.公平锁

    • 在等待队列中,按照申请顺序获取锁

    6.非公平锁

    • 在等待队列中,随机的抽取线程获取锁
    • synchronized、ReentrantLock
    • 优点:性能高于公平锁,可以重复利用CPU的时间

    7.自旋锁

    • A线程上锁之后,B线程调用A线程的时候会不断循环等待解锁。此时其他的线程就不能再调用A了
    • 常见的自旋锁:TicketLock,CLHLock,MSCLock
    • 优点:减少了上下文切换
    • 缺点:不断的循环增加CPU消耗

    8.CAS和自旋锁的区别

    自旋锁(spinlock):是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。
    
    获取锁的线程一直处于活跃状态,但是并没有执行任何有效的任务,使用这种锁会造成busy-waiting。
    它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。
    
    两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,”自旋”一词就是因此而得名。
    
    
    CAS(Compare-and-Swap),即比较并替换,是一种实现并发算法时常用到的技术,Java并发包中的很多类都使用了CAS技术。
    
    这里以AtomicInteger说明一下:
    public final int incrementAndGet() {
            for (;;) {
                int current = get();
                int next = current + 1;
                if (compareAndSet(current, next))
                    return next;
            }
        }
    加1就是先获取当前值,加1,设置时先对比当前值是不是内存中的值,如果是设置新值。
    
    内存对比是通过本地方法实现的,需要操作系统的支持。
    
    如果成功就可以退出循环,否则一直尝试。
    
    用AtomicReference实现自旋锁
    自旋锁就是线程调用lock()后,其他线程再调用lock()会卡住,等待锁的释放。
    
    public class SpinLock {
        private AtomicReference<Thread> lock = new AtomicReference<Thread>();
        public void lock() {
            Thread current = Thread.currentThread();
            // 利用CAS
            while (!lock.compareAndSet(null, current)) {
                // DO nothing
            }
        }
        public void unlock() {
            Thread current = Thread.currentThread();
            lock.compareAndSet(current, null);
        }
    }
    
    可以看出,第一个线程调用lock()时lock没有set过值,对象是null,第二个线程在调用时已经set过值,所以会一直循环。
    只有当第一个线程unlock()之后第二个循环才能结束。
    
    
    古今成大事者,不唯有超世之才,必有坚韧不拔之志!
  • 相关阅读:
    清除浮动的方式
    网页在线测试工具
    仿京东左侧菜单 hover效果-简易demo
    原生js,插入元素
    知识补漏
    css3动画
    java微信开发(wechat4j)——支持微信JS-SDK的jsapi_ticket中控服务器
    java微信开发(wechat4j)——access_token中控服务器实现
    java微信开发(wechat4j)——wechat4j配置文件解读
    java微信开发(wechat4j)——设置响应微信参数
  • 原文地址:https://www.cnblogs.com/songwp/p/14595943.html
Copyright © 2011-2022 走看看