多线程并发的一些问题解决(讲的全面而且非常棒)

CAS 属于乐观锁

CAS称为Compare And Swap 即 比较和替换 ,它是对于JVM底层的原子操作,他的参数有三个 内存地址,旧的预期值,新的修改值 当内存地址的值与旧的预期值相等时,才可以将其更新为新的修改值,Unsafe类提供了硬件级别的原子操作

https://blog.csdn.net/qq_32998153/article/details/79529704

http://www.pianshen.com/article/1008104738/

automic

底层原理也是自旋+CAS

https://blog.csdn.net/h2604396739/article/details/86720618

Sychronized、volatile的内存语义

Synchronized的内存语义是monitor(可以理解为监视器),当该线程monitor值为0,该线程进去monitor,monitor设置为1,如果该线程已经占有monitor,只是重新进入,monitor+1,如果其他线程已经占用了monitor,则该线程进入阻塞状态,直到monitor的进入数为0,再重新尝试获取monitor的所有权。

volatile的内存语义为 写时本地内存中的变量值刷新给主存,读是本地内存失效直接从主存中读

https://blog.csdn.net/daide2012/article/details/59116527

什么是伪共享?以及怎么发生的伪共享及如何解决?

伪共享是在多线程中 两个变量共用一个缓存行带来的性能问题

解决可以为三种 1.缓存行为64字节 LOng为8字节 所以一个缓存行有八个位置,所以在两个变量中加七个long变量

2.设置自己的Long属性

3.使用JDK内置的注解,但需要在JVM启动时更改参数

https://www.jianshu.com/p/7758bb277985

ThreadLocal原理

threadlocal原理就是在其中有一个内置threaLocalMap,ThreadLocalMap中存放一个entry数组,map的key存放threadlocal对象,value存放的是数据,可以看到ThreadLocalMap中的Entry是继承WeakReference的,其中ThreadLocal是以弱引用形式存在Entry中,如果ThreadLocal在外部没有被强引用,那么垃圾回收的时候就会被回收掉,又因为Entry中的value是强引用,就会出现内存泄漏。虽然ThreadLocal源码中的会对这种情况进行了处理,但还是建议不需要用TreadLocal的时候,手动调remove方法。

https://www.jianshu.com/p/69ae8c213b30

inheritableThreadlocal

inheritableThreadLocal 重写了父类 ThreadLocal的三个方法createMap()和 getMap(),通过子线程创建时把父线程的信息全部复制过来,childvalue()保证了父和子两个线程不互相影响。

https://blog.csdn.net/c764193441/article/details/80728611

AQS 

AQS 是抽象队列同步器,他的底层是AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch ,他包括一个volatile int 类型的stale和一个FIFO(双向队列)线程等待队列,这个AQS内部还有一个关键变量,用来记录当前加锁的是哪个线程,初始化状态下,这个变量是null。当线程获取stale的值为 0时可以获取锁,当其他线程访问是stale为1时 就会到阻塞队列尾部,直到stale为0时释放锁,阻塞队列头部去获取stale 。对stale操作为CAS操作

https://blog.csdn.net/savorTheFlavor/article/details/88804667

https://www.cnblogs.com/fanBlog/p/9336126.html

StampedLock

JAVA 1.8新增的锁 在ReentrantReadWriteLock上的优化 解决了读写锁读写互斥带来的读写互斥、写写互斥问题,可以在读的时候写,是乐观锁,在读的时候发现有写操作就再读一次,每回都要返回 邮票(Stamp) 为0是表示失败,其他都为成功,跟AQS中stale的感觉差不多,但stale是1表示有线程获取锁。

https://segmentfault.com/a/1190000015808032?utm_source=tag-newest

http://blog.sina.com.cn/s/blog_6f5e71b30102xfsb.html

CountDownLatch

内部syn也是使用AQS机制,通过构造函数简单的传值,但是ReentrantLock传的stale的值为锁的次数,而CountDownLatch的是计数值的大小,CountDownLatch 是主线程等待,主线程如果等待呢?就是AQS中的自旋 只有当count为0时才跳出循环,否则一直死循环全部子线程完成后开始运行,主线程等待调用await(),当count为0时,主线程开始运行

https://blog.csdn.net/u014653197/article/details/78217571

countdownLatch与join的区别为join必须使线程全部执行完 而countdown可以分阶段

https://blog.csdn.net/u010142437/article/details/80395538

如何避免futuretask使用不当造成线程一直阻塞?

在get方法是添加参数过期时间,因为stale每次都是new  只有等于具体值normal是才正常执行

http://ju.outofmemory.cn/entry/337358

高并发如何限流?

漏桶、令牌桶、计数器三种方式。

https://segmentfault.com/a/1190000019896078

线程池

线程池的初始化有4种 为单例、固定大小、Cache即Integer.max-1、还有一个固定长度而且以延迟或定时的方式实行任务

线程池的拒接任务策略有四种

1.丢弃任务抛出RejectedExecutionException异常

2.丢弃任务不抛出异常

3.舍弃队列最前面的任务,然后尝试执行该任务(重复执行)

4.有调用线程执行任务

https://blog.csdn.net/weixin_28760063/article/details/81266152

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昭阳.

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值