北京网站设计技术乐云seo丹东制作网站公司

web/2025/9/30 9:50:12/文章来源:
北京网站设计技术乐云seo,丹东制作网站公司,济南市城市建设集团网站,桓台建设局网站LockSupport类是Java6(JSR166-JUC)引入的一个类#xff0c;提供了基本的线程同步原语。LockSupport实际上是调用了Unsafe类里的函数#xff0c;归结到Unsafe里#xff0c;只有两个函数#xff1a; park#xff1a;阻塞当前线程(Block current thread),字面理解park#x…LockSupport类是Java6(JSR166-JUC)引入的一个类提供了基本的线程同步原语。LockSupport实际上是调用了Unsafe类里的函数归结到Unsafe里只有两个函数  park阻塞当前线程(Block current thread),字面理解park就算占住停车的时候不就把这个车位给占住了么起这个名字还是很形象的。 unpark: 使给定的线程停止阻塞(Unblock the given thread blocked )。 public native void unpark(Thread jthread);  public native void park(boolean isAbsolute, long time);     isAbsolute参数是指明时间是绝对的还是相对的。 仅仅两个简单的接口就为上层提供了强大的同步原语。 先来解析下两个函数是做什么的。 unpark函数为线程提供“许可(permit)”线程调用park函数则等待“许可”。这个有点像信号量但是这个“许可”是不能叠加的“许可”是一次性的。 比如线程B连续调用了三次unpark函数当线程A调用park函数就使用掉这个“许可”如果线程A再次调用park则进入等待状态。 注意unpark函数可以先于park调用。比如线程B调用unpark函数给线程A发了一个“许可”那么当线程A调用park时它发现已经有“许可”了那么它会马上再继续运行。 实际上park函数即使没有“许可”有时也会无理由地返回这点等下再解析。 park和unpark的灵活之处 上面已经提到unpark函数可以先于park调用这个正是它们的灵活之处。 一个线程它有可能在别的线程unPark之前或者之后或者同时调用了park那么因为park的特性它可以不用担心自己的park的时序问题否则如果park必须要在unpark之前那么给编程带来很大的麻烦 考虑一下两个线程同步要如何处理 在Java5里是用wait/notify/notifyAll来同步的。wait/notify机制有个很蛋疼的地方是比如线程B要用notify通知线程A那么线程B要确保线程A已经在wait调用上等待了否则线程A可能永远都在等待。编程的时候就会很蛋疼。 另外是调用notify还是notifyAll notify只会唤醒一个线程如果错误地有两个线程在同一个对象上wait等待那么又悲剧了。为了安全起见貌似只能调用notifyAll了。 park/unpark模型真正解耦了线程之间的同步线程之间不再需要一个Object或者其它变量来存储状态不再需要关心对方的状态。   HotSpot里park/unpark的实现 每个java线程都有一个Parker实例Parker类是这样定义的   [cpp] view plaincopy class Parker : public os::PlatformParker {  private:    volatile int _counter ;    ...  public:    void park(bool isAbsolute, jlong time);    void unpark();    ...  }  class PlatformParker : public CHeapObjmtInternal {    protected:      pthread_mutex_t _mutex [1] ;      pthread_cond_t  _cond  [1] ;      ...  }   可以看到Parker类实际上用Posix的mutexcondition来实现的。   在Parker类里的_counter字段就是用来记录所谓的“许可”的。 当调用park时先尝试直接能否直接拿到“许可”即_counter0时如果成功则把_counter设置为0,并返回   [cpp] view plaincopy void Parker::park(bool isAbsolute, jlong time) {    // Ideally wed do something useful while spinning, such    // as calling unpackTime().        // Optional fast-path check:    // Return immediately if a permit is available.    // We depend on Atomic::xchg() having full barrier semantics    // since we are doing a lock-free update to _counter.    if (Atomic::xchg(0, _counter)  0) return;       如果不成功则构造一个ThreadBlockInVM然后检查_counter是不是0如果是则把_counter设置为0unlock mutex并返回   [cpp] view plaincopy ThreadBlockInVM tbivm(jt);  if (_counter  0)  { // no wait needed    _counter  0;    status  pthread_mutex_unlock(_mutex);     否则再判断等待的时间然后再调用pthread_cond_wait函数等待如果等待返回则把_counter设置为0unlock mutex并返回   [cpp] view plaincopy if (time  0) {    status  pthread_cond_wait (_cond, _mutex) ;  }  _counter  0 ;  status  pthread_mutex_unlock(_mutex) ;  assert_status(status  0, status, invariant) ;  OrderAccess::fence();   当unpark时则简单多了直接设置_counter为1再unlock mutext返回。如果_counter之前的值是0则还要调用pthread_cond_signal唤醒在park中等待的线程     [cpp] view plaincopy void Parker::unpark() {    int s, status ;    status  pthread_mutex_lock(_mutex);    assert (status  0, invariant) ;    s  _counter;    _counter  1;    if (s  1) {       if (WorkAroundNPTLTimedWaitHang) {          status  pthread_cond_signal (_cond) ;          assert (status  0, invariant) ;          status  pthread_mutex_unlock(_mutex);          assert (status  0, invariant) ;       } else {          status  pthread_mutex_unlock(_mutex);          assert (status  0, invariant) ;          status  pthread_cond_signal (_cond) ;          assert (status  0, invariant) ;       }    } else {      pthread_mutex_unlock(_mutex);      assert (status  0, invariant) ;    }  }   简而言之是用mutex和condition保护了一个_counter的变量当park时这个变量置为了0当unpark时这个变量置为1。值得注意的是在park函数里调用pthread_cond_wait时并没有用while来判断所以posix condition里的Spurious wakeup一样会传递到上层Java的代码里。   关于Spurious wakeup参考上一篇bloghttp://blog.csdn.net/hengyunabc/article/details/27969613   [cpp] view plaincopy if (time  0) {    status  pthread_cond_wait (_cond, _mutex) ;  }     这也就是为什么Java dos里提到当下面三种情况下park函数会返回   Some other thread invokes unpark with the current thread as the target; orSome other thread interrupts the current thread; orThe call spuriously (that is, for no reason) returns.  相关的实现代码在 http://hg.openjdk.java.net/build-infra/jdk7/hotspot/file/52c4a1ae6adc/src/share/vm/runtime/park.hpphttp://hg.openjdk.java.net/build-infra/jdk7/hotspot/file/52c4a1ae6adc/src/share/vm/runtime/park.cpphttp://hg.openjdk.java.net/build-infra/jdk7/hotspot/file/52c4a1ae6adc/src/os/linux/vm/os_linux.hpphttp://hg.openjdk.java.net/build-infra/jdk7/hotspot/file/52c4a1ae6adc/src/os/linux/vm/os_linux.cpp   其它的一些东东 Parker类在分配内存时使用了一个技巧重载了new函数来实现了cache line对齐。   [cpp] view plaincopy // We use placement-new to force ParkEvent instances to be  // aligned on 256-byte address boundaries.  This ensures that the least  // significant byte of a ParkEvent address is always 0.     void * operator new (size_t sz) ;   Parker里使用了一个无锁的队列在分配释放Parker实例     [cpp] view plaincopy volatile int Parker::ListLock  0 ;  Parker * volatile Parker::FreeList  NULL ;    Parker * Parker::Allocate (JavaThread * t) {    guarantee (t ! NULL, invariant) ;    Parker * p ;      // Start by trying to recycle an existing but unassociated    // Parker from the global free list.    for (;;) {      p  FreeList ;      if (p   NULL) break ;      // 1: Detach      // Tantamount to p  Swap (FreeList, NULL)      if (Atomic::cmpxchg_ptr (NULL, FreeList, p) ! p) {         continue ;      }        // Weve detached the list.  The list in-hand is now      // local to this thread.   This thread can operate on the      // list without risk of interference from other threads.      // 2: Extract -- pop the 1st element from the list.      Parker * List  p-FreeNext ;      if (List  NULL) break ;      for (;;) {          // 3: Try to reattach the residual list          guarantee (List ! NULL, invariant) ;          Parker * Arv   (Parker *) Atomic::cmpxchg_ptr (List, FreeList, NULL) ;          if (Arv  NULL) break ;            // New nodes arrived.  Try to detach the recent arrivals.          if (Atomic::cmpxchg_ptr (NULL, FreeList, Arv) ! Arv) {              continue ;          }          guarantee (Arv ! NULL, invariant) ;          // 4: Merge Arv into List          Parker * Tail  List ;          while (Tail-FreeNext ! NULL) Tail  Tail-FreeNext ;          Tail-FreeNext  Arv ;      }      break ;    }      if (p ! NULL) {      guarantee (p-AssociatedWith  NULL, invariant) ;    } else {      // Do this the hard way -- materialize a new Parker..      // In rare cases an allocating thread might detach      // a long list -- installing null into FreeList --and      // then stall.  Another thread calling Allocate() would see      // FreeList  null and then invoke the ctor.  In this case we      // end up with more Parkers in circulation than we need, but      // the race is rare and the outcome is benign.      // Ideally, the # of extant Parkers is equal to the      // maximum # of threads that existed at any one time.      // Because of the race mentioned above, segments of the      // freelist can be transiently inaccessible.  At worst      // we may end up with the # of Parkers in circulation      // slightly above the ideal.      p  new Parker() ;    }    p-AssociatedWith  t ;          // Associate p with t    p-FreeNext        NULL ;    return p ;  }      void Parker::Release (Parker * p) {    if (p  NULL) return ;    guarantee (p-AssociatedWith ! NULL, invariant) ;    guarantee (p-FreeNext  NULL      , invariant) ;    p-AssociatedWith  NULL ;    for (;;) {      // Push p onto FreeList      Parker * List  FreeList ;      p-FreeNext  List ;      if (Atomic::cmpxchg_ptr (p, FreeList, List)  List) break ;    }  }       总结与扯谈 JUC(Java Util Concurrency)仅用简单的park, unpark和CAS指令就实现了各种高级同步数据结构而且效率很高令人惊叹。转载于:https://www.cnblogs.com/bendantuohai/p/4653543.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/84393.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中国空间站简介100字网站未备案可以做经营活动吗

登陆SAP 之后,菜单下面一行,最右边的那个彩色按钮(SAP GUI),点击“选项”-可视设计-字体设计-固定狂赌字体设计,点击:选择字体 即可。转载于:https://www.cnblogs.com/RogerLu/p/9612648.html

公司网站建设费用包括哪些免费做网站的公司

目录 一、JShell 二、Dynamic Class-File Constants类文件新添的一种结构 三、局部变量类型推断(var ”关键字”) 四、新加的一些实用API 1. 新的本机不可修改集合API 2. Stream 加强 3. String 加强 4. Optional 加强 5. 改进的文件API 五、移…

自己在线制作logo免费网站心理学门户网站开发与实现

🍅 点击文末小卡片 ,免费获取网络安全全套资料,资料在手,涨薪更快 研判(入侵检测) 研判我理解为人工层面对入侵检测事件进行再分析,即借助已有的设备告警根据经验判断是否为真实action 研判工作…

昆山公司网站建设电话免费网站建设 免备案

JIRA 重建索引加快速度 JIRA数据量大时,做一遍reindex的速度会很慢,经常需要几个小时 这是后需要查看CPU,如果做reindex时候CPU占用率不高,增加 index的线程数以加快 reindex 配置步骤 停止掉JIRA在home目录下的 jira-config.…

南充北京网站建设域名价格排行

目录 一、EnableWebMvcSecurity 二、MvcRequestMatcher 三、AuthenticationPrincipal 四、异步 Spring MVC 整合 五、Spring MVC 和 CSRF 整合 1、自动包含 Token 2、解析 CsrfToken Spring Security提供了一些与Spring MVC的可选整合。本节将进一步详细介绍这种整合。 …

h5网站制作价格大连企业做网站

TCP是通过确认机制和超时重传机制实现可靠传输 UDP UDP它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结…

asp企业网站源码docker wordpress 备份

学习是有境界的,下面以C语言中的结构型为例简单分析。 第一种境界:理解了。 结构型是自定义数据类型,与C语言中基本的数据类型如int的作用相同,用于定义变量。(变量是内存中存储单元的标识,C语言中通过变…

数字营销 h5 网站开发外包岗位为什么不能去

目录 面试官:redis的分片集群有什么作用 面试官:Redis分片集群中数据是怎么存储和读取的? 面试官:redis的分片集群有什么作用 候选人:分片集群主要解决的是,海量数据存储的问题,集群中有多个m…

网站制作 常见问题广告设计与制作需要学什么专业

用手机号申请了163免费邮箱,在网页端或手机网易邮箱客户端可以正常登录,但在电脑Foxmail客户端中,按相同的邮件服务器进行设置,显示密码不正确。难道163邮箱已经不支持PC中的Foxmail客户端了吗?让我们一同探究解决之道…

用织梦网站后台发布文章为什么还需要审核河南开封网站建设

id:19 A.三数论大小(引用) 题目描述 输入三个整数,然后按照从大到小的顺序输出数值。 要求:定义一个函数,无返回值,函数参数是三个整数参数的引用,例如int &a, int &b, int &c。…

检察院网站建设自查如何做360购物网站

目录 前言 一、设计理念 1.1 支持不同的计算设备与计算单元 1.2 存储空间的分配与维护 1.2.1 简单内存池的实现 1.3 浅拷贝与写操作检测 1.4 底层接口扩展 1.5 类型转换与求值 1.6 数据接口与规范 前言 一个深度学习框架的初步实现为例,讨论如何在一个相对…

怎么给网站添加图标做视频有收益的网站

目录 dirsearch下载地址: githack下载(一次不成功可多试几次) 一、什么是Git 1.git结构 2.git常用命令及示例 3.Git泄露原理 二、Git泄露 1.Log 2.Stash 3.Index 工具准备:dirsearch、githack dirsearch下载地址: GitHub - mauroso…

猎奇网站源码垂直类网站怎么做

在当今的自动化工业领域,川崎工业机器人以其卓越的性能和可靠的工作效率赢得了广泛的赞誉。作为机器人的核心组成部分,伺服电机的作用至关重要。然而,就像所有机械设备一样,也可能会遭遇电机磨损或故障,需要适时的川崎…

龙岗区网站建设哪个公司好东莞网站制作百年

目录 说明: 1. 参数模型(全局字典) 2. 实现过程(C) 创建功能包 参数命令行的使用 YAML参数文件 rosparam命令 使用示例 编程方法(C) 配置代码编译规则 编译并运行 编译 运行 3. 实…

保定模板建站哪家好淮南网站建设

最近很无聊.....得到了3天假期~~~ 于是乎把Ubuntu10.10下载下来安装了 结果第二天root用户就登陆不上了 进入单用户模式后读shower文件发现密码那就一"!" 真是奇怪.... 之前在网上查说passwd命令没加载... 结果明明加载了 改了之后终于用上root权限了 结果又是惨…

企业网站规划书范文如何做网站诊断

使用conda或anaconda的小伙伴们都知道,图形界面时不靠谱的,而在命令行下,所有的操作就会稳定很多,且极少出现问题。因此,熟记conda的命令行就变得十分有用。但对于我这样近50岁依旧奋斗在代码第一线的大龄程序员而已&a…

网站推广文案手机网站怎么导入微信

本文来自pilishen.com----原文链接; 欢迎来和pilishen一起学习php&Laravel;学习群:109256050OAuth2是一个安全框架,控制着程序受保护部分的准入,主要是控制不同的客户端如何来调取API,保证它们在请求相应资源的时候…

网站前台 后台无限免费视频直播

前言 在一个句子,哪怕其中的每个单词都拼写正确,而且语法也无懈可击,仍然可能有歧义或者并非书写者希望表达的意思。程序也有可能表面上是一个意思,而实际上的意思却相差甚远。本篇讲述了几种可能引起上述歧义的程序书写方式 1、…

建设网站工作室如何管理好一个团队

配置 昇腾 Ascend C/C 开发环境 flyfish 这里以Orange Pi Ai Pro 为例 先说如何配置MindStudio,然后再说如何查看Orange Pi Ai Pro的一些信息 Orange Pi AI Pro 开发板是香橙派联合华为精心打造的高性能AI 开发板,其搭载了昇腾 AI 处理器。Linux 桌面…

企业网站建设费属于办公费吗整站排名优化公司

如今为了适应需求的不断变化,动态表单设计器应运而生。它主要是为了满足界面的不断变化和提高开发速度。比如:一些页面客户可能也无法确定页面的终于布局,控件的位置,在哪种情况下显示或不显示等可能须要随时改动。为了应对这些需…