笔记--java内存模型

单线程中,如果后面代码依赖于前面的代码,就不会发生指令重排。
锁定规则:如果一个锁处于被锁状态,一定执行unlock后才能lock。
变量规则:volatile,如果一个线程先写了volatile变量,另一个线程再读取的值一定是写之后的值。
线程启动规则:一个线程通过B.start()启动B,A对变量的修改一定对B可见。
线程中断规则:interrupt()方法调用先于被中断线程的代码检测,直到中断。(即外部调用interrupt方法肯定执行在线程里面检测到被中断之前)
线程终结规则:A调用B.join()等B终止,B终止前对共享变量的修改对A可见。
对象初始化:对象初始化完成在它的finalize()之前。

reentrantlock可以传入true设置公平锁,根据请求锁的顺序去得到锁执行代码。

读写锁(ReentrantReadWriterLock):
通过new创建该对象,有两个锁,在写锁没有释放前,读锁会等待。
共享锁(CountDownLatch):
通过计数的方式记录当前有几个线程持有锁,增加一个线程则计数+1,没有到达最大数值(例如10)则允许线程持有并执行,否则等待。

Object可以作为锁的原因:每个对象头重都含有一个Monitor(实现类为ObjectMonitor)。

ObjectMonitor维护了一个waitSet,一个EntryList,记录处于wait状态的线程和block状态的线程。owner为正在执行的线程

owner执行的线程执行notify,则将waitSet中的线程放到entrySet中,重新竞争锁。

Java对synchronized的优化:
1、自旋:让线程等一段时间,看持有锁的线程是否释放。基本用不到,浪费CPU。
2、轻量级锁:线程会交替持有锁,基本不会等待,如果不交替,就变重量级锁。
3、偏向锁:线程获得偏向锁,没有其他线程竞争锁,则该线程再次进入同步代码块,不会占锁/释放锁。(判断锁对象中的ThreadId是否相同,相同则不需再加锁)。有线程竞争会变轻量级锁

AQS:

总结,ReentrantLock里面维护一个Sync变量,NonfairSync和fairSync是其实现类,Sync继承自AQS,所以ReentrantLock就拥有了AQS的功能,当获取锁的时候,会执行AQS的compareAndSetState方法,将state设置有锁状态,其他线程获取锁的时候会添加到获取队列中。在acquiredQueued中,如果在等待队列头部,就再尝试下获取锁,不行再执行线程挂起操作。

获取锁流程:
1、acquire通过调用子类自定义的tryAcquire获取锁
2、如果没获取到,addWaiter将线程封装成Node插入队列尾部
3、在acquireQueued中用自旋方式尝试获取锁,失败就判断是否将线程阻塞,若阻塞执行LockSupport的native方法阻塞

唤醒流程:
调用unlock方法,从队列一开始去判断status,找到第一个状态非cancel的节点,执行LockSupport的unpark方法

线程池工作原理:(阿里严禁使用Excutors创建线程池)
Worker集合:本质是一个HashSet,保存所有的线程。
等待队列:corePoolSize满时,保存在等待队列,本质BlockingQueue。等待队列再满才添加最大线程数
ctl:AtomicInteger类型,高3位保存线程池状态(RUNNING:接收新任务并处理排队任务。
SHUTDOWN:不接受新任务,但处理排队任务。调用shutdown()
STOP:不接受新任务,不处理排队任务,中断正在运行的任务。调用shutdownnow()
TIDYING:所有任务停止且workerCount为0时为这个状态,然后运行terminate()方法
TERMINATED:调用terminate()方法后为此状态),低29位保存线程数量。

keepAliveTime是用来针对超过核心线程数后的最大线程,空闲到达这个时间直接销毁。

我们需要定义RejectedExecutionHandler,如果所有的任务无法加入corePoolSize、等待队列、maxSize,又没有定义该handler,就会抛
RejectedExecutionException异常。

阿里禁止使用原因:newFixedThreadPool、newSingleThreadExecutor会创建无边界的等待队列,当队列中任务很多时,会OOM。
newCachedThreadPool的最大线程数是int最大值,当核心线程耗时久的时候,线程池会创建新线程执行任务,内存不足会OOM。

 

DVM启动的时候,只有一个堆,当Zygote fork进程时已经使用的称为Zygote堆,没使用的称为Active堆,后续需要分配对象的时候都在Active上进行。


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值