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

网页转app工具张家港做网站优化排名

网页转app工具,张家港做网站优化排名,电商 网站建设,淄博网站建设淄博转载自 详解Java多线程编程中LockSupport类的线程阻塞用法 LockSupport类是Java6(JSR166-JUC)引入的一个类#xff0c;提供了基本的线程同步原语。LockSupport实际上是调用了Unsafe类里的函数#xff0c;归结到Unsafe里#xff0c;只有两个函数#xff1a; public native…转载自  详解Java多线程编程中LockSupport类的线程阻塞用法 LockSupport类是Java6(JSR166-JUC)引入的一个类提供了基本的线程同步原语。LockSupport实际上是调用了Unsafe类里的函数归结到Unsafe里只有两个函数 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类是这样定义的 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,并返回 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并返回 ThreadBlockInVM tbivm(jt);  if (_counter  0)  { // no wait needed    _counter  0;    status  pthread_mutex_unlock(_mutex);   否则再判断等待的时间然后再调用pthread_cond_wait函数等待如果等待返回则把_counter设置为0unlock mutex并返回 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中等待的线程 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 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/jdk7/jdk7/hotspot/file/81d815b05abb/src/share/vm/runtime/park.hpp http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/81d815b05abb/src/share/vm/runtime/park.cpp http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/81d815b05abb/src/os/linux/vm/os_linux.hpp http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/81d815b05abb/src/os/linux/vm/os_linux.cpp 其它的一些东东 Parker类在分配内存时使用了一个技巧重载了new函数来实现了cache line对齐。 // 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实例 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指令就实现了各种高级同步数据结构而且效率很高令人惊叹。 在C程序员各种自制轮子的时候Java程序员则有很丰富的并发数据结构如locklatchqueuemap等信手拈来。 要知道像C直到C11才有标准的线程库同步原语但离高级的并发数据结构还有很远。boost库有提供一些线程同步相关的类但也是很简单的。Intel的tbb有一些高级的并发数据结构但是国内boost都用得少更别说tbb了。 最开始研究无锁算法的是C/C程序员但是后来很多Java程序员或者类库开始自制各种高级的并发数据结构经常可以看到有分析Java并发包的文章。反而C/C程序员总是在分析无锁的队列算法。高级的并发数据结构比如并发的HashMap没有看到有相关的实现或者分析的文章。在C11之后这种情况才有好转。 因为正确高效实现一个Concurrent Hash Map是很困难的要对内存CPU有深刻的认识而且还要面对CPU不断升级带来的各种坑。 我认为真正值得信赖的C并发库只有Intel的tbb和微软的PPL。 https://software.intel.com/en-us/node/506042     Intel® Threading Building Blocks  http://msdn.microsoft.com/en-us/library/dd492418.aspx   Parallel Patterns Library (PPL) 另外FaceBook也开源了一个C的类库里面也有并发数据结构。 https://github.com/facebook/folly
http://www.sadfv.cn/news/49138/

相关文章:

  • 网站的大图标怎么做Wordpress 图片之间空隙
  • 网站建设公司怎么盈利做ppt模板的网站有哪些
  • 如何搭建一个视频网站网站建设与管理课程设计
  • 营销型网站网站网站建设虚拟主机
  • 广州企业网站哪家好小程序推广怎么赚钱
  • 关于网站建设的入门书wordpress 黑色
  • 网页设计门户网站英文网站的外部链接 建设
  • 网站后台修改图片网络公司网站制作岗位职责
  • 深圳网站开发公司哪家好成都搜索引擎优化推广维护
  • 快速排名优化已有的网站如何做排名优化
  • 百度网站好评贵州省建设厅造价通官方网站
  • 如何向搜索引擎提交网站网站 推广商系统 设计
  • 门户网站开发如何提高产品排名佛山网站免费制作
  • 写着网站建设图片网站做联盟还赚钱吗
  • 专题类响应式网站建设怎么样建设自己网站
  • 公司做网站的费属于广告费么国内做网站大公司
  • php做网站做的比较好的家具网站首页
  • 如何做黑彩网站网站开发与开发
  • 个人电子商务网站建设沈阳企业网站制作公司
  • 长春市做网站网站建设销售方面会遇到的问题
  • 网站流量大小对网站有什么影响免费商用图片的网站
  • 建设通网站是筑龙网的吗制作wordpress模板教程
  • 天河网站建设公司餐饮招商加盟网站建设
  • 产品推广网站设计中山seo扣费
  • 注册网站时手机号格式不正确分类达人介绍
  • 深圳微信网站建设报价湖北响应式网站制作
  • php做的卖水果网站建设网站的网址
  • 家庭电影网站建设百度小程序注册流程
  • php做网站时间代码小程序开店流程
  • 联系方式 响应式网站如何能去医疗网站做编辑