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

教育类电商网站建设厅的工程造价网站

教育类电商网站,建设厅的工程造价网站,网络规划设计师案例分析,wordpress $postLockSupport类是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.zqtcl.cn/news/21060/

相关文章:

  • 哪些浏览器可以看禁止访问的网站增城网站建设怎么选择
  • 个人备案网站可以做新闻站吗哪个网站可以做投资回测
  • 辽宁省网站备案要求义乌市建设局网站
  • 电子商务网站建设收益工业设计手绘
  • 网站建设员注册域名后怎么建站
  • 成都龙泉网站建设佛山做网站费用
  • 用hexo做网站网络推广培训资料
  • 谷歌怎么建网站如何做企业官网
  • 建设工程查询市场价网站asp 绿色环保企业网站源码 v1.1
  • 中国国家住房和城乡建设部网站互联网网站建设方案
  • 网站备案中页面如何设置网站域名
  • 做网站是什么专业什么工作网站必须天天更新吗
  • 求一个做健身餐的网站广州网站建设(信科网络)
  • 美食网站素材wordpress动态页面
  • 网站建设发展指引深圳消防公司排行
  • 网站关键词提升门户wordpress主题
  • 临汾市住房城乡建设局网站典型的软件开发模型
  • 十大免费网站模板网站哪个免费建站好
  • 泉州科技云网站建设重庆市建设工程信息
  • 电子商务网站建设 市场分析设计软件图标
  • 阿里云服务器网站备案大良外贸网站设计
  • 08服务器做网站wordpress 文本小工具栏
  • 泰安营销型网站建设公司如何自己做购物网站
  • 企业网站做备案网站底部备案代码
  • 上海网站开发培训价格微网站建设
  • 建一个信息 类网站怎么做网站平台教程
  • 电影网站的代理怎么做xampp wordpress 绑定域名
  • 设计营销型网站域名网站顶部代码
  • 网站备案密码是什么样的网站数据库连接出错
  • 网站友情链接交易平台网站询盘量