当前位置: 首页 > news >正文

浙江平安建设信息系统网站千阳做网站

浙江平安建设信息系统网站,千阳做网站,吉林哪里做网站,已经注册了域名怎么做简单的网站目录 介绍AQS: 直观方式解释加锁的流程#xff1a; Node是什么#xff1a;它里面有什么属性呢 图解队列的排队过程#xff1a; 源码分析三种加锁流程#xff1a; 我们先讲解一下非公平锁的加锁流程#xff1a; Lock()方式加锁#xff1a; 在源码里对于Lock()的解…目录 介绍AQS: 直观方式解释加锁的流程 Node是什么它里面有什么属性呢 图解队列的排队过程 源码分析三种加锁流程 我们先讲解一下非公平锁的加锁流程 Lock()方式加锁 在源码里对于Lock()的解释 源码详解枷锁的过程 进入lock方法后显示 进入sync.lock();方法 展示非公平锁的实现lock() 展示公平锁实现的lock() 产看方法acquire(1); 查看方法tryAcquire(int arg) 非公平锁实现 公平锁实现 查看创建Node的方法addWaiter(Node.EXCLUSIVE) 查看方法acquireQueued 查看方法shouldParkAfterFailedAcquire 注Node()状态 tryLock()方式加锁 tryLock()方式 tryLock(long time, TimeUnit unit)方式 tryAcquireNanos方法 doAcquireNanos: cancelAcquire() lockInterruptibly方式 acquireInterruptibly()方法 doAcquireInterruptibly()方法 在我们打开源码时可以看一下这个源码的作者 /** since 1.5* author Doug Lea*/ Doug Lea 是 Java 并发编程领域的权威人物他在并发编程方面的贡献尤为突出。Doug Lea 是 SUNY Oswego 的计算机科学教授并且是纽约先进技术中心软件工程实验室的联合主任。他的工作对 Java 并发编程产生了深远的影响。 Doug Lea 撰写了《JAVA并发编程实践》一书这本书是 Java 领域的经典之作全面深入地探讨了 Java 平台上的多线程和并发编程技术。这本书不仅帮助开发者理解和掌握如何在 Java 环境中编写高效、安全且可维护的并发代码还提供了许多标准设计技术用于解决常见的并发编程挑战。 Doug Lea 在 Java 并发编程中的另一个重要贡献是开发了 java.util.concurrent 包这个包在 JDK 5.0 中被整合极大地丰富了 Java 的并发编程工具。这个包包括了线程池、并发集合、原子变量和锁等工具极大地简化了并发编程的复杂性。 介绍AQS: 全程为AbstractQueuedSynchronizer AQS中文被称为队列同步器 AQS是一个抽象的接口。他是JUC包下的基类。JUC包下的很多功能都是基于AQS实现的。 AQS里面维护了一个由volitile修饰的state变量和内置的FIFO队列完成线程的排队和加锁操作。 volitile维护的state保证了可见性和有序性在设置state是里面提供了compareAndSetState()方法。CAS方式保证了原子性 直观方式解释加锁的流程 为大家图解什么是FIFO队列队列里的数据类型是什么。是如何连接的 FIFO队列是双向链表实现的。 里面每个节点的数据类型是Node 特殊的是队列的头节点是一个伪节点这个节点的线程信息是null Node是什么它里面有什么属性呢 Node是AQS的内部类。 为大家展示Node的结构 里面记录着状态前置的指针后置的指针还记录了队列的头节点和尾节点 图解队列的排队过程 这个图片只是为了展现这个队列的状态对于流程我们并没直接的展现但是需要注意的是伪节点的Thread是null. 源码分析三种加锁流程 我们先讲解一下非公平锁的加锁流程 如果线程A执行CAS将state修改为1则线程1得到所资源执行业务代码。 这时线程B在去获取所资源是发现state不是0并且自己并不是有锁的线程那么B将自己封装为Node进入双向队列。 但是在进入队列是头节点必须是一个伪节点若一开始没有伪节点那就创建之后将这个节点挂在伪节点后将前置节点的状态修改为-1 之后就可以挂起线程 我们在创建ReentrantLock()时都是借助多态创建.在此为大家展示一下lock的API Lock()方式加锁 在源码里对于Lock()的解释 Acquires the lock. If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock has been acquired. Implementation Considerations A Lock implementation may be able to detect erroneous use of the lock, such as an invocation that would cause deadlock, and may throw an (unchecked) exception in such circumstances. The circumstances and the exception type must be documented by that Lock implementation. 获取锁。 如果锁不可用则当前线程将出于线程调度目的而被禁用并在获取锁之前处于休眠状态。 实施注意事项 实现 Lock 可能能够检测到对锁的错误使用例如会导致死锁的调用并可能在这种情况下引发未经检查的异常。该实现必须记录 Lock 情况和异常类型。 源码详解枷锁的过程 进入lock方法后显示 public void lock() {sync.lock();} 进入sync.lock();方法 abstract void lock();//发现是抽象方法。 展示非公平锁的实现lock() final void lock() {//首先进入之后直接使用CAS方式修改如果成功将持有锁的线程设置为当前线程返回if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());else  //失败进入acquire方法acquire(1);} 展示公平锁实现的lock() final void lock() {//发现公平锁下的方式就是 acquire(1);     acquire(1); } 产看方法acquire(1); public final void acquire(int arg) {//尝试获取线程如果为获取if (!tryAcquire(arg) //开始方法acquireQueuedaddWaiter(Node.EXCLUSIVE), arg)//addWaiter(Node.EXCLUSIVE)开始封装Node对象 Node.EXCLUSIVE这个指的是现在的锁的类型时互斥锁//封装后讲数据直接开始放置到队列里面acquireQueued(addWaiter(Node.EXCLUSIVE), arg))//将自己终端就是在队列里面排队等待唤醒selfInterrupt();} 查看方法tryAcquire(int arg) protected boolean tryAcquire(int arg) {throw new UnsupportedOperationException(); } 非公平锁实现 protected final boolean tryAcquire(int acquires) {return nonfairTryAcquire(acquires); } 进入方法nonfairTryAcquire(acquires) final boolean nonfairTryAcquire(int acquires) {//设置线程为当前线程final Thread current Thread.currentThread();//获取stateint c getState();//c0 没有线程持有锁抢一把if (c 0) {//CAS方式枪锁成功设置一下当前线程直接返回trueif (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}//state不是0,但是线程时但该案当前线程锁重入 state1 直接返回获取锁成功else if (current getExclusiveOwnerThread()) {int nextc c acquires;//放置state超过int最大值if (nextc 0) // overflowthrow new Error(Maximum lock count exceeded);//设置state的值setState(nextc);return true;}//未成功返回false 返回的是flase之后开始将这个线程放入到FIFO队列里return false; } 公平锁实现 protected final boolean tryAcquire(int acquires) {//获取当前线程final Thread current Thread.currentThread();//获取state的值int c getState();//如果是0的话这里展现的是公平锁的君子风范if (c 0) {//如果里面没有Node或者是头节点之后没有Node等待或者自己就是头节点之后的点那就可以尝试拿锁if (!hasQueuedPredecessors() //如果成功 返回truecompareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}//state不是0,但是线程时但该案当前线程锁重入 state1 直接返回获取锁成功else if (current getExclusiveOwnerThread()) {int nextc c acquires;//放置state超过int最大值if (nextc 0)throw new Error(Maximum lock count exceeded);//设置state的值setState(nextc);return true;}//未成功返回false;返回的是flase之后开始将这个线程放入到FIFO队列里return false;} //就是判断公平锁是否能够干活 public final boolean hasQueuedPredecessors() {// The correctness of this depends on head being initialized// before tail and on head.next being accurate if the current// thread is first in queue.Node t tail; // Read fields in reverse initialization orderNode h head;Node s;return h ! t ((s h.next) null || s.thread ! Thread.currentThread()); } 查看创建Node的方法addWaiter(Node.EXCLUSIVE) /** *就是简单的创建一个node */ private Node addWaiter(Node mode) {Node node new Node(Thread.currentThread(), mode);// Try the fast path of enq; backup to full enq on failureNode pred tail;if (pred ! null) {node.prev pred;if (compareAndSetTail(pred, node)) {pred.next node;return node;}}enq(node);return node;} 查看方法acquireQueued //对于lock()方法里面的中断操作我们先忽略。 final boolean acquireQueued(final Node node, int arg) {//设置状态当前未获取到锁资源boolean failed true;try {boolean interrupted false;//死循环必须完成一件事 for (;;) {//查找当前节点的前驱节点final Node p node.predecessor();//开始判断如果我的前置节点就是伪节点注意是伪节点直接在词使用tryAcquire()尝试获取锁资源if (p head tryAcquire(arg)) {//如果成功就设置一些头节点setHead(node);p.next null; // help GC//设置已经获取锁资源failed false;//返回的值是false.return interrupted;}//如果前置节点不是伪节点的话if (shouldParkAfterFailedAcquire(p, node) parkAndCheckInterrupt())interrupted true;}} finally {if (failed)cancelAcquire(node);}} 查看方法shouldParkAfterFailedAcquire private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {int ws pred.waitStatus;//如果等于-1 证明前置节点可以唤醒当前节点  if (ws Node.SIGNAL) return true;if (ws 0) {//如果是0的话就是当前前置节点无效使用循环找到有效的节点地将当前节点挂在有效节点的后面do {node.prev pred pred.prev;} while (pred.waitStatus 0);pred.next node;} else {//那就是-2-3使用ACS将状态设置为-1compareAndSetWaitStatus(pred, ws, Node.SIGNAL);}return false;} 注Node()状态 /** waitStatus value to indicate thread has cancelled */static final int CANCELLED  1;/** waitStatus value to indicate successors thread needs unparking */static final int SIGNAL     -1;/** waitStatus value to indicate thread is waiting on condition */static final int CONDITION -2;/*** waitStatus value to indicate the next acquireShared should* unconditionally propagate*/static final int PROPAGATE -3; tryLock()方式加锁 tryLock()方式 public boolean tryLock() {//这就是非公平锁的TryAcquire()方法return sync.nonfairTryAcquire(1); } final boolean nonfairTryAcquire(int acquires) {//设置线程为当前线程final Thread current Thread.currentThread();//获取stateint c getState();//c0 没有线程持有锁抢一把if (c 0) {//CAS方式枪锁成功设置一下当前线程直接返回trueif (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}//state不是0,但是线程时但该案当前线程锁重入 state1 直接返回获取锁成功else if (current getExclusiveOwnerThread()) {int nextc c acquires;//放置state超过int最大值if (nextc 0) // overflowthrow new Error(Maximum lock count exceeded);//设置state的值setState(nextc);return true;}//未成功返回false 返回的是flase之后开始将这个线程放入到FIFO队列里return false; } tryLock(long time, TimeUnit unit)方式 public boolean tryLock(long timeout, TimeUnit unit)throws InterruptedException {return sync.tryAcquireNanos(1, unit.toNanos(timeout)); } tryAcquireNanos方法 public final boolean tryAcquireNanos(int arg, long nanosTimeout)throws InterruptedException {//如果线程中断抛出异常if (Thread.interrupted())throw new InterruptedException();return tryAcquire(arg) //在抢一手失败的话执行下面的方法||doAcquireNanos(arg, nanosTimeout);} doAcquireNanos: private boolean doAcquireNanos(int arg, long nanosTimeout)throws InterruptedException {//如果时间结束直接返回失败if (nanosTimeout 0L)return false;//设置结束时间final long deadline System.nanoTime() nanosTimeout;//将当前节点设置出来final Node node addWaiter(Node.EXCLUSIVE);//设置时候失败获取锁boolean failed true;try {for (;;) {  //这是死循环我们注意查看代码的出口//获取当前节点的前置节点final Node p node.predecessor();//如果前置节点是伪节点尝试拿锁if (p head tryAcquire(arg)) {setHead(node);p.next null; // help GCfailed false;//成功直接返回return true;}//计算现在还剩多长时间nanosTimeout deadline - System.nanoTime();//时间结束直接返回falseif (nanosTimeout 0L)return false;//时间还是有的修改前置节点的状态准备挂起if (shouldParkAfterFailedAcquire(p, node) //时间有但是太少了连挂起的时间都不足也是结束nanosTimeout spinForTimeoutThreshold)//如果时间足够开始将节点挂起 继续死循环等待结束条件LockSupport.parkNanos(this, nanosTimeout);//如果当前线程被其他线程中断直接甩出异常if (Thread.interrupted())throw new InterruptedException();}} finally {//甩出异常也是结束死循环但是需要将节点取消if (failed)cancelAcquire(node);}} cancelAcquire() private void cancelAcquire(Node node) {//如果是null 直接返回if (node null)return;//将当前节点的线程设置为nullnode.thread null;//找到前置线程Node pred node.prev;//找到状态正常的前置节点while (pred.waitStatus 0)node.prev pred pred.prev;// 将前置线程的next设置为当前线程的nextNode predNext pred.next;// 设置状态为1代表节点取消node.waitStatus Node.CANCELLED;// 如果是尾节点的话直接就是简单的将前置节点设知为尾节点if (node tail compareAndSetTail(node, pred)) {//设置前置节点的next为空compareAndSetNext(pred, predNext, null);} else {//当前的节点不是尾节点或者是CAS操作失败//那就是两种情况一种是前置节点就是伪节点 第二种是前置接点不是伪节点int ws;if (pred ! head //前置节点不是伪节点((ws pred.waitStatus) Node.SIGNAL //前置节点状态是否为-1 || //不是-1的话或着是其他的0的状态设置为-1 这样的话可以将线程唤醒(ws 0 compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) //并且前置的线程不是nullpred.thread ! null) {Node next node.next;//判断当前线程有后继节点将后继节点关在前置节点上if (next ! null next.waitStatus 0)compareAndSetNext(pred, predNext, next);} else {//当前节点的前置节点是伪节点 直接将线程唤醒 这是释放锁的操作在后续的章节开始讲解unparkSuccessor(node);}node.next node; // help GC} } lockInterruptibly方式 public void lockInterruptibly() throws InterruptedException {sync.acquireInterruptibly(1); } acquireInterruptibly()方法 public final void acquireInterruptibly(int arg)throws InterruptedException {//判断线程是否终端if (Thread.interrupted())throw new InterruptedException();//如果尝试获取所资源失败if (!tryAcquire(arg))//进入方法doAcquireInterruptibly(arg); } doAcquireInterruptibly()方法 private void doAcquireInterruptibly(int arg)throws InterruptedException {final Node node addWaiter(Node.EXCLUSIVE);//当前获取资源失败boolean failed true;try {for (;;) //注意出口条件//获取当前节点的前置节点final Node p node.predecessor();//如果前置节点是伪节点尝试拿锁if (p head tryAcquire(arg)) {setHead(node);p.next null; // help GCfailed false;//成功直接返回return true;}//获取锁资源失败 开始挂起资源如果挂起之后被中断的方式挂起抛出异常if (shouldParkAfterFailedAcquire(p, node) parkAndCheckInterrupt())throw new InterruptedException();}} finally {//因为异常也是出口条件将节点取消if (failed)cancelAcquire(node);//还是取消节点的方法同上} }
http://www.tj-hxxt.cn/news/223754.html

相关文章:

  • 怎么制作网站步骤房管局网站做房查
  • 做运动特卖的网站织梦开发供需网站
  • 嘉兴 网站 建设珠海市企业网站制作平台
  • 厦门市建设质量安全协会网站长沙互联网企业
  • 北京的餐饮网站建设c 网站开发环境
  • 免费域名网站黄丁的老头seo博客
  • 做网站多钱长沙招聘
  • 合肥seo网站推广费用网站外链接自己可以怎么做
  • 免费发布信息不收费的网站网站建设预览
  • 佛山网站设计电话创建一个网站的创业计划书
  • 徐州市中宇建设工程有限公司网站量个网站一个域名
  • asp网站部署html5农业网站模板
  • 自适应网站开发seo国外网络推广
  • wordpress 仿站工具如何做网站推广方式
  • 百度建设网站建设民政局网站需要多少钱
  • 湖北网站制作公司的联系方式做网站的价格是多少
  • 做一个营销型网站有哪些内容宁波人流网
  • 惠州网页模板建站做伞的外国网站
  • 网站开发流程有几个阶段十堰网站设计公司
  • 企业品牌网站建设我们的优势青海城乡建设部网站
  • 网站优化的学习注册安全工程师考试时间
  • 如何做一个企业的网站谷歌seo网站怎么做产品分类
  • 网站开发的技术问题北京室内设计公司排名榜
  • 网站建设html5源码wordpress手机端插件下载
  • 购物网站管理层深圳网站制作公司报价单
  • 外贸网站建设soho网络营销主页
  • 国外做水广告网站大全关于网站建设广告词
  • 做女朋友网站河北邯郸永利ktv视频
  • 网站的301重定向怎么做安徽建设工程信息管理平台
  • 做一个网站flash收多少钱优化网站内链