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

godaddy网站建设教程优秀软文范例100字

godaddy网站建设教程,优秀软文范例100字,企业网站建设 网络服务,中英文企业网站php源码目录 Condition接口一、 Condition介绍及使用二、 Condition接口方法描述(基于jdk1.8)三、 Condition实现分析3.1 等待队列3.2 await()等待3.3 signal() 通知Condition接口 一、 Condition介绍及使用 Condition接口是为了与Lock配合实现等待/通知模式, 可以将Condition等待通知…

目录

  • Condition接口
    • 一、 Condition介绍及使用
    • 二、 Condition接口方法描述(基于jdk1.8)
    • 三、 Condition实现分析
      • 3.1 等待队列
      • 3.2 await()等待
      • 3.3 signal() 通知

Condition接口

一、 Condition介绍及使用

Condition接口是为了与Lock配合实现等待/通知模式, 可以将Condition等待通知和Lock的关系 与 Object的等待通知和Synchronized的关系类比;

  • Synchronized是通过锁对象即Object的wait() 和 notify() 实现等待通知;
  • Lock 则可以通过Condition的await() 和 signal() 实现等待通知;

Object的监视器方法与Condition接口对比如下图:

1254098-20180728133432375-205577043.png

Condition对象定义了等待通知两种类型的方法, Condition对象有Lock对象(调用newCondition()方法)创建, Condition对象依赖于Lock对象;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class ConditionTest {private static Lock lock = new ReentrantLock();private static Condition condition = lock.newCondition();public static void main(String[] args) throws InterruptedException {new Thread(() -> {try {conditionWait();} catch (InterruptedException e) {e.printStackTrace();}}).start();//Thread.sleep(100);new Thread(() -> { conditionSignal(); }).start();}public static void conditionWait() throws InterruptedException {lock.lock();try{System.out.println("start wait");condition.await();System.out.println("wait end");}finally {lock.unlock();}}public static void conditionSignal() {lock.lock();try{System.out.println("signal");condition.signal();}finally {lock.unlock();}}
}
--- 输出:
start wait
signal
wait end

二、 Condition接口方法描述(基于jdk1.8)

1254098-20180728135340625-2072568787.png

三、 Condition实现分析

3.1 等待队列

以ConditionObject为例, ConditionObject是同步器AbstractQueuedSynchronizer内部类; 每个Condition对象都包含一个等待队列, 该队列是实现通知等待的关键; 队列节点使用的是AbstractQueuedSynchronizer.Node

 public class ConditionObject implements Condition, java.io.Serializable {private static final long serialVersionUID = 1173984872572414699L;/** First node of condition queue. */private transient Node firstWaiter; // 队首/** Last node of condition queue. */private transient Node lastWaiter; // 队尾
}

等待队列结构:
1254098-20180728140520607-923930500.png

3.2 await()等待

1254098-20180728143839418-834508348.png
调用Condition的await()方法, 会使当前线程进入等待队列并释放锁, 同时线程变为等待状态;

public final void await() throws InterruptedException {if (Thread.interrupted())throw new InterruptedException();Node node = addConditionWaiter(); // 将当前线程添加到等待队列队尾// 调用AbstractQueuedSynchronizer的方法, 释放掉当前线程持有的资源state, 并唤醒同步队列中下一个后继节点long savedState = fullyRelease(node); int interruptMode = 0;while (!isOnSyncQueue(node)) {LockSupport.park(this); // 最终还是依靠unsafe.park()实现的if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)break;}if (acquireQueued(node, savedState) && interruptMode != THROW_IE)interruptMode = REINTERRUPT;if (node.nextWaiter != null) // clean up if cancelledunlinkCancelledWaiters(); // 删除等待队列中等待状态不为CONDIITON的节点if (interruptMode != 0)reportInterruptAfterWait(interruptMode);
}
// 将当前线程添加到等待队列队尾
private Node addConditionWaiter() {Node t = lastWaiter;// If lastWaiter is cancelled, clean out.if (t != null && t.waitStatus != Node.CONDITION) {unlinkCancelledWaiters(); // 删除等待队列中等待状态不为CONDIITON的节点t = lastWaiter;}// 将当前线程封装成Node对象添加到等待队列队尾// 由于调用await()的前提是已经获取了锁, 所以下面操作不需要进行线程同步Node node = new Node(Thread.currentThread(), Node.CONDITION);if (t == null)firstWaiter = node;elset.nextWaiter = node;lastWaiter = node;return node;
}// 遍历等待队列, 删除队列节点中等待状态不为CONDITION(表示在Condition队列中等待)的节点
private void unlinkCancelledWaiters() {Node t = firstWaiter;Node trail = null;while (t != null) {Node next = t.nextWaiter;if (t.waitStatus != Node.CONDITION) {t.nextWaiter = null;if (trail == null)firstWaiter = next;elsetrail.nextWaiter = next;if (next == null)lastWaiter = trail;}elsetrail = t;t = next;}
}// AbstractQueuedSynchronizer中的方法, 释放掉当前线程持有的资源state, 并唤醒同步队列中下一个后继节点
final long fullyRelease(Node node) {boolean failed = true;try {long savedState = getState(); // 获取当前线程所占有的资源if (release(savedState)) { // 将资源释放, 并唤醒同步队列中的后继节点failed = false;return savedState;} else { // 资源释放失败, 抛出异常throw new IllegalMonitorStateException();}} finally {if (failed) // 资源释放失败, 将该节点状态标记为CANCELLED(1)node.waitStatus = Node.CANCELLED;}
}

3.3 signal() 通知

1254098-20180728144117086-267487895.png

  • Condition的signal()方法, 将唤醒在等待队列中等待时间最长的节点(首节点), 在唤醒节点前, 会将节点移动到同步队列中;
public final void signal() {if (!isHeldExclusively()) // 判断当前线程是否获取了锁; 未获取锁则抛出异常throw new IllegalMonitorStateException();Node first = firstWaiter;if (first != null)doSignal(first); // 唤醒头结点
}
// 将first节点添加到同步队列尾部, 如果失败则尝试唤醒下一个节点;
private void doSignal(Node first) {do {if ( (firstWaiter = first.nextWaiter) == null)lastWaiter = null;first.nextWaiter = null;} while (!transferForSignal(first) &&(first = firstWaiter) != null);
}
// 将node添加到同步队列尾部, 并尝试将其唤醒
final boolean transferForSignal(Node node) {/** If cannot change waitStatus, the node has been cancelled.*/if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))return false;/** Splice onto queue and try to set waitStatus of predecessor to* indicate that thread is (probably) waiting. If cancelled or* attempt to set waitStatus fails, wake up to resync (in which* case the waitStatus can be transiently and harmlessly wrong).*/Node p = enq(node);int ws = p.waitStatus;if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))LockSupport.unpark(node.thread); // 最终还是依靠unsafe.unpark()实现的return true;
}
  • Condition的signalAll()方法, 相当于对等待队列中每个节点执行一次signal()方法;
/*** Moves all threads from the wait queue for this condition to* the wait queue for the owning lock.** @throws IllegalMonitorStateException if {@link #isHeldExclusively}*         returns {@code false}*/
public final void signalAll() {if (!isHeldExclusively())throw new IllegalMonitorStateException();Node first = firstWaiter;if (first != null)doSignalAll(first);
}
/**
* Removes and transfers all nodes.
* @param first (non-null) the first node on condition queue
*/
private void doSignalAll(Node first) {lastWaiter = firstWaiter = null;do {Node next = first.nextWaiter;first.nextWaiter = null;transferForSignal(first);first = next;} while (first != null);
}

转载于:https://www.cnblogs.com/jxkun/p/9381822.html

http://www.lbrq.cn/news/2383705.html

相关文章:

  • 建设六马路小学 网站千锋教育官方网
  • 什么网站值得做河南seo网站多少钱
  • 自己有域名要怎么制作网站电商运营培训哪个机构好
  • 网站建设丨选择金手指排名15高端网站建设公司
  • 福州 网站建设百度竞价优化排名
  • 如何快速建立一个网站必应搜索网站
  • 黄冈app推广服务机构seo排名优化公司
  • 阿里云做网站官网跨境电商营销推广
  • 宜昌永东建设网站营销策略的思路
  • 大连做网站海外推广渠道都有哪些
  • ssh网站开发公司品牌宣传
  • 建外贸网站用什么主机百度seo效果
  • 手机网站怎么做微信登陆seo诊断专家
  • 国内优秀app界面设计案例专业seo公司
  • 做网站建设公司赚钱网络推广渠道都有哪些
  • 珠海专业网站制作百度一下官网
  • 外贸网站域名能用cn做后缀吗免费制作链接
  • 做好的网站百度推广客服电话24小时
  • 重庆网站建设cqhtwl百度搜索排名优化
  • 北京哪家做网站seo怎么弄
  • 做网上任务赚钱的网站市场seo是什么
  • 泰国如何做网站推广万网官网首页
  • 网络搭建与维护是什么广州百度网站排名优化
  • 网站备案 暂住证企业营销案例
  • 做知识产权相关的网站百度推广账号登陆入口
  • 湘潭做网站推荐磐石网络网络优化的流程
  • 专业做公墓 陵园的网站优化落实疫情防控新十条
  • 推荐企业门户网站建设2022近期时事热点素材摘抄
  • wordpress主题集成插件下载seo优化点击软件
  • 网站模块设计怎么做怎样打开网站
  • VMC850立式加工中心Y轴传动机械结构设计cad【7张】三维图+设计说明书
  • CCF编程能力等级认证GESP—C++3级—20250628
  • postman接口测试,1个参数有好几个值的时候如何测试比较简单快速?
  • [spring6: PointcutAdvisor MethodInterceptor]-简单介绍
  • 构建智能客服Agent:从需求分析到生产部署
  • 【Linux手册】缓冲区:深入浅出,从核心概念到实现逻辑