各种锁策略

ThreadLocal缺点:
1.不可继承性;
2.脏数据(线程池会复用静态变量);
3.内存溢出(线程池是长生命周期的);
设计模式:
一、单例设计模式:
作用:提升程序性能;
定义:整个程序的运行中,只存储一个对象;
分类:饿汉模式、懒汉模式
1.饿汉模式:上来不管三七二十一直接创建一个对象(随着类启动而启动,所以线程安全);

public class Main2 {
    static class Singleton{
        //1.创建私有构造方法
        private Singleton(){}
        //2.创建一个私有的类对象
        private volatile static Singleton singleton=null;
        //3.提供统一的访问入口
        public static Singleton getInstance(){
            if(singleton==null){
                synchronized (Singleton.class) {
                    if(singleton==null){
                    singleton = new Singleton();
                    }
                }
            }
            return singleton;
        }
    }
    public static Singleton s1=null;
    public static Singleton s2=null;
    public static void main(String[] args) throws InterruptedException {
        Thread thread=new Thread(new Runnable() {
            @Override
            public void run() {
                s1=Singleton.getInstance();
            }
        });
        thread.start();
        s2=Singleton.getInstance();
        thread.join();
        System.out.println(s1==s2);
    }
}

缺点:程序启动之后就会创建,但创建之后可能不会使用,从而浪费系统资源;
2.懒汉模式:当程序启动不会进行初始化,什么时候调用,什么时候创建;

public class Main2 {
    static class Singleton{
        //1.创建私有构造方法
        private Singleton(){}
        //2.创建一个私有的类对象
        private volatile static Singleton singleton=null;
        //3.提供统一的访问入口
        public static Singleton getInstance(){
            if(singleton==null){
                synchronized (Singleton.class) {
                    if(singleton==null){
                    singleton = new Singleton();
                    }
                }
            }
            return singleton;
        }
    }
    public static Singleton s1=null;
    public static Singleton s2=null;
    public static void main(String[] args) throws InterruptedException {
        Thread thread=new Thread(new Runnable() {
            @Override
            public void run() {
                s1=Singleton.getInstance();
            }
        });
        thread.start();
        s2=Singleton.getInstance();
        thread.join();
        System.out.println(s1==s2);
    }
}

new一个对象的过程:先在内存中开辟空间、初始化、将变量指向内存区域;
二、工厂模式(简单工厂、抽象工厂)
三、模板模式
自定义阻塞队列:
生产者消费者模型——生产者生产数据,消费者消费生产者生产的数据;
生产者阻塞点:当数据量满了以后,不要尝试给队列给队列添加数据了,而是阻塞等待(wait+notify/notifyAll、LockSupport.park/unpark);
消费者阻塞点:当队列中没有数据;
乐观锁与悲观锁(策略)
乐观锁:它认为一般情况下不会出现并发冲突,所以只有在进行数据更新时候,才会检测并发冲突,如果没有冲突则执行修改,如果有冲突则返回失败。
应用:CAS(Compare And Swap(比较并且交换)乐观锁)、ABA、JUC
CAS是一种机制,比较内存值和旧值是否相同,相同就将内存值修改,否则自旋重新更新旧值,重复操作。
CAS的三个组成部分:V(内存值)、A(旧值)、B(新值)
V==A?true(没有并发冲突)->V->B:false(并发冲突)
线程不安全解决方案:
1.加锁;
2.ThreadLocal;
3.Atomic*(乐观锁实现);
CAS底层实现原理?
Java层面CAS的实现是UnSafe类;而UnSafe类调用了C++的本地方法,通过调用操作系统的Atomic::cmpxchg的指令实现的;
乐观锁性能比较高;但存在A(预期旧值)B(新值)A(预期旧值)问题
ABA统一的解决方案:引入版本号,每次修改之后更新版本号;
悲观锁:它认为通常情况下会出现并发冲突,它所以在一开始就加锁。
synchronized是属于悲观锁的。
共享锁与非共享锁:
共享锁是指一个锁可以被多个线程拥有,非共享锁是指一个锁只能被一个线程拥有。
读写锁(把一把锁分成两部分,一个用于读数据的锁,另一个用于写数据)中的读锁就是共享锁,写锁是非共享锁;——具体实现:ReentrantReaderWriterLock
优势:将锁的内容更加的细化;
注意事项:读写锁中的读锁和写锁是互斥的;
公平锁和非公平锁:
公平锁:锁的获取顺序必须和线程访问的先后顺序保持一致;(执行有序,结果可预期)
ReentrantLock(true)…
非公平锁:锁的获取顺序和线程获取锁的顺序无关;
ReentrantLock()/synchronized…
自旋锁:通过死循环一直尝试获取锁;缺点是没有得到锁的话会一直死循环,造成程序性能问题
可重入锁:例如synchronized

public static void main(String[] args) {
        Object o=new Object();
        synchronized (o){
            System.out.println("第一次进入锁");
            synchronized (o){
                System.out.println("第二次进入锁");
            }
        }
    }

你是怎么理解乐观锁和悲观锁的,具体实现?
1.乐观锁:CAS-》Atomic*,CAS是由V、A、B三部分组成,然后执行的时候是使用V==A对比,如果结果为true,则表明没有并发冲突,则可直接修改,否则不能修改。CAS是通过调用C++的UnSafe中的本地方法(CompareAndSwapXXX)来实现的,C++是通过调用操作系统的原子指令Atomic::cmpxchg来实现的;
2.悲观锁:例如synchronized,java层面每一个锁对象存储在对象头,对象头中有一个偏向线程ID,这个标志着这个锁被哪个线程持有,JVM层面是实现了监视器锁,自动加锁和释放锁,操作系统层面是由互斥锁Mutex实现;
syunchronized锁优化(锁消除):
JDK1.6锁升级过程:
无锁-》偏向锁(第一个线程第一次访问)将线程ID存入对象头的偏向锁标识-》轻量级锁(自旋)-》重量级锁(性能低)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值