??xml version="1.0" encoding="utf-8" standalone="yes"?>午夜视频在线观看精品中文,a天堂中文在线官网,国产欧美精品一区二区三区四区http://www.aygfsteel.com/stevenjohn/category/54681.html那些青春的岁?/description>zh-cnTue, 14 Jun 2016 14:05:19 GMTTue, 14 Jun 2016 14:05:19 GMT60聊聊高ƈ发系l之限流Ҏ-1http://www.aygfsteel.com/stevenjohn/archive/2016/06/14/430882.htmlabinabinTue, 14 Jun 2016 05:38:00 GMThttp://www.aygfsteel.com/stevenjohn/archive/2016/06/14/430882.htmlhttp://www.aygfsteel.com/stevenjohn/comments/430882.htmlhttp://www.aygfsteel.com/stevenjohn/archive/2016/06/14/430882.html#Feedback0http://www.aygfsteel.com/stevenjohn/comments/commentRss/430882.htmlhttp://www.aygfsteel.com/stevenjohn/services/trackbacks/430882.html阅读全文

abin 2016-06-14 13:38 发表评论
]]>
关于单CPUQ多CPU上的原子操作http://www.aygfsteel.com/stevenjohn/archive/2015/04/20/424546.htmlabinabinMon, 20 Apr 2015 06:02:00 GMThttp://www.aygfsteel.com/stevenjohn/archive/2015/04/20/424546.htmlhttp://www.aygfsteel.com/stevenjohn/comments/424546.htmlhttp://www.aygfsteel.com/stevenjohn/archive/2015/04/20/424546.html#Feedback0http://www.aygfsteel.com/stevenjohn/comments/commentRss/424546.htmlhttp://www.aygfsteel.com/stevenjohn/services/trackbacks/424546.html所谓原子操?是"不可中断的一个或一pd操作" ?/span>

gU的原子操作Q?/span>
在单处理器系l?UniProcessor)中,能够在单条指令中完成的操作都可以认ؓ? 原子操作"Q因Z断只能发生于指o之间。这也是某些CPU指opȝ中引入了test_and_set、test_and_clear{指令用于界资源互斥的原因?/span>

在对U多处理?Symmetric Multi-Processor)l构中就不同了,׃pȝ中有多个处理器在独立地运行,即能在单条指o中完成的操作也有可能受到q扰?/span>

在x86 q_上,CPU提供了在指o执行期间Ҏȝ加锁的手DcCPU芯片上有一条引U?HLOCK pinQ如果汇~语a的程序中在一条指令前面加上前~"LOCK"Q经q汇~以后的机器代码׃CPU在执行这条指令的时候把#HLOCK pin的电位拉低,持箋到这条指令结束时攑ּQ从而把ȝ锁住Q这样同一ȝ上别的CPU暂时不能通过ȝ讉K内存了,保证了这条指令在多处理器环境中的

原子性?/span>
软gU的原子操作Q?/span>
软gU的原子操作实现依赖于硬件原子操作的支持?/span>
对于linux而言Q内核提供了两组原子操作接口Q一l是针对整数q行操作Q另一l是针对单独的位q行操作?/span>
2.1. 原子整数操作
针对整数的原子操作只能对atomic_tcd的数据处理。这里没有用C语言的intcdQ主要是因ؓQ?/span>

1) 让原子函数只接受atomic_tcd操作敎ͼ可以保原子操作只与q种Ҏcd数据一起?/span>

2) 使用atomic_tcd保~译器不对相应的D行访问优?/span>

3) 使用atomic_tcd可以屏蔽不同体系l构上的数据cd的差异。尽Linux支持的所有机器上的整型数据都?2位,但是使用atomic_t的代码只能将该类型的数据当作24位来使用。这个限制完全是因ؓ在SPARC体系l构上,原子操作的实C同于其它体系l构Q?2位intcd的低8位嵌入了一个锁Q因为SPARC体系l构对原子操作缺乏指令的支持,所以只能利用该锁来避免对原子类型数据的q发讉K?/span>

原子整数操作最常见的用途就是实现计数器。原子整数操作列表在中定义。原子操作通常是内敛函敎ͼ往往通过内嵌汇编指o来实现。如果某个函数本来就是原子的Q那么它往往会被定义成一个宏?/span>

在编写内核时Q操作也单:

atomic_t use_cnt;

atomic_set(&use_cnt, 2);

atomic_add(4, &use_cnt);

atomic_inc(use_cnt);

2.2. 原子性与序?/span>

原子性确保指令执行期间不被打断,要么全部执行Q要么根本不执行。而顺序性确保即使两条或多条指o出现在独立的执行U程中,甚至独立的处理器上,它们本该执行的顺序依然要保持?/span>

2.3. 原子位操?/span>

原子位操作定义在文g中。o人感到奇怪的是位操作函数是对普通的内存地址q行操作的。原子位操作在多数情况下是对一个字长的内存讉KQ因而位可位于0-31之间(?4位机器上?-63之间),但是对位L范围没有限制?/span>

~写内核代码Q只要把指向了你希望的数据的指针l操作函敎ͼ可以进行位操作了:

unsigned long word = 0;

set_bit(0, &word); /*W?位被讄*/

set_bit(1, &word); /*W?位被讄*/

clear_bit(1, &word); /*W?位被清空*/

change_bit(0, &word); /*{W??/

Z么关注原子操作?
1Q在认一个操作是原子的情况下Q多U程环境里面Q我们可以避免仅仅ؓ保护q个操作在外围加上性能开销昂贵的锁?/span>
2Q借助于原子操作,我们可以实现互斥锁?/span>
3Q借助于互斥锁Q我们可以把一些列操作变ؓ原子操作?/span>

GNU C中x++是原子操作吗Q?/span>
{案不是。x++?条指令完成。x++在单CPU下不是原子操作?/span>
对应3条汇~指?/span>
movl x, %eax
addl $1, %eax
movl %eax, x
在vc2005下对?/span>
++x;
004232FA mov eax,dword ptr [x]
004232FD add eax,1
00423300 mov dword ptr [x],eax
仍然?条指令?/span>
所?+xQx++{都不是原子操作。因其步骤包括了从内存中取x值放入寄存器Q加寄存器,把值写入内存三个指令?/span>

如何实现x++的原子性?
在单处理器上Q如果执行x++Ӟ止多线E调度,可以实现原子。因为单处理的多U程q发是伪q发?/span>
在多处理器上Q需要借助cpu提供的Lock功能。锁ȝ。读取内存|修改Q写回内存三步期间禁止别的CPU讉Kȝ。同时我估计使用Lock指o锁ȝ的时候,OS也不会把当前U程调度C。要是调CQ那麻烦了?/span>

在多处理器系l中存在潜在问题的原因是Q?/span>
不用LOCK指o前缀锁定ȝ的话Q在一ơ内存访问周期中有可能其他处理器会生异常或中断Q而在异常处理中有可能会修改尚未写入的地址Q这样当INC操作完成后会产生无效数据Q覆盖了前面的修改)?/span>

spinlock 用于CPU同步, 它的实现是基于CPU锁定数据ȝ的指?
当某个CPU锁住数据ȝ? 它读一个内存单?spinlock_t)来判断这个spinlock 是否已经被别的CPU锁住. 如果? 它写q一个特定? 表示锁定成功, 然后q回. 如果? 它会重复以上操作直到成功, 或者spinơ数过一个设定? 锁定数据ȝ的指令只能保证一个机器指令内, CPU独占数据ȝ.
单CPU当然能用spinlock, 但实C无需锁定数据ȝ.

spinlock在锁定的时?如果不成?不会睡眠,会持l的试,单cpu的时候spinlock会让其它process动不?

abin 2015-04-20 14:02 发表评论
]]>
sun.misc.Unsafehttp://www.aygfsteel.com/stevenjohn/archive/2015/03/15/423475.htmlabinabinSun, 15 Mar 2015 15:42:00 GMThttp://www.aygfsteel.com/stevenjohn/archive/2015/03/15/423475.htmlhttp://www.aygfsteel.com/stevenjohn/comments/423475.htmlhttp://www.aygfsteel.com/stevenjohn/archive/2015/03/15/423475.html#Feedback0http://www.aygfsteel.com/stevenjohn/comments/commentRss/423475.htmlhttp://www.aygfsteel.com/stevenjohn/services/trackbacks/423475.html     几句关于Unsafe的ƈ发性。compareAndSwapҎ?em>原子?q且可用来实现高性能的、无锁的数据l构。比?考虑问题:在用大量线E的׃n对象上增长倹{?..
     Java是一门安全的~程语言Q防止程序员犯很多愚蠢的错误Q它们大部分是基于内存管理的。但是,有一U方式可以有意的执行一些不安全、容易犯错的操作Q那是使用UnsafecR?br />    CAS操作?个操作数Q内存值MQ预期值EQ新值UQ如果M==EQ则内存g改ؓBQ否则啥都不做?br />    sun.misc.Unsafeq个cL如此C安全Q以至于JDK开发者增加了很多Ҏ限制来访问它。它的构造器是私有的Q工厂方?span style="color: #993300;">getUnsafe()的调用器只能被Bootloader加蝲。如你在下面代码片段的第8行所见,q个家伙甚至没有被Q何类加蝲器加载,所以它的类加蝲器是null。它会抛?span style="color: #993300;">SecurityException 异常来阻止R入者?br />    public final class Unsafe {
   ...
   private Unsafe() {}
   private static final Unsafe theUnsafe = new Unsafe();
   ...
   public static Unsafe getUnsafe() {
      Class cc = sun.reflect.Reflection.getCallerClass(2);
      if (cc.getClassLoader() != null)
          throw new SecurityException("Unsafe");
      return theUnsafe;
   }
   ...
}
q运的是q里有一个Unsafe的变量可以被用来取得Unsafe的实例。我们可以轻村֜~写一个复制方法通过反射来实玎ͼ如下所C:
Q?a target="_blank" rel="nofollow">http://highlyscalable.wordpress.com/2012/02/02/direct-memory-access-in-java/Q?/div>
public static Unsafe getUnsafe() {
   try {
           Field f = Unsafe.class.getDeclaredField("theUnsafe");
           f.setAccessible(true);
           return (Unsafe)f.get(null);
   } catch (Exception e) {
       /* ... */
   }
}

Unsafe一些有用的Ҏ?/strong>

  1. 虚拟?#8220;集约?#8221;QVM intrinsificationQ:如用于无锁Hash表中的CASQ比较和交换Q。再比如compareAndSwapIntq个Ҏ用JNI调用Q包含了对CAS有特D引导的本地代码。在q里你能d更多关于CAS的信息:http://en.wikipedia.org/wiki/Compare-and-swap?/li>
  2. L虚拟机(译注Q主拟机主要用来理其他虚拟机。而虚拟^台我们看到只有guest VMQ的sun.misc.Unsafe功能能够被用于未初始化的对象分配内存Q用allocateInstanceҎQ,然后构造器调用解释为其他方法的调用?/li>
  3. 你可以从本地内存地址中追t到q些数据。?span style="color: #993300;">java.lang.Unsafec获取内存地址是可能的。而且可以通过unsafeҎ直接操作q些变量Q?/li>
  4. 使用allocateMemoryҎQ内存可以被分配到堆外。例如当allocateDirectҎ被调用时DirectByteBuffer构造器内部会?span style="color: #993300;">allocateMemory?/li>
  5. arrayBaseOffset?span style="color: #993300;">arrayIndexScaleҎ可以被用于开发arrayletsQ一U用来将大数l分解ؓ对象、限制扫描的实时消耗或者在大对象上做更新和Ud?/li>

Unsafe.java是jdkq发cdjava.util.concurrent包中使用的底层类Q该cM的方法都是通过nativeҎ调用操作pȝ命o?/p>

    在多U程环境下,主要存在两种Ҏ的场景:

    1Q多个线E同时访问某个对象的ҎQ由于操作系l对U程调度的不定性,存在使该对象的状态处于不一致的状态,Z避免q种情况的发生,我们可以声明该方法ؓ同步ҎQsynchronizedQ。保证某一时刻只有一个线E调用该ҎQ其它调用线E则被阻塞。这U方法在q发性很高的情况下会产生大量的线E调度开销。从而媄响程序的q发性能。在java.util.concurrent包中通过使用非阻塞原子方法,减少操作pȝ的无用线E调度开销Q从而提高ƈ发性能?/p>

   2Q多U程通过某个对象q行通信Q即常见的生产者消费者模型。在以前的jdk版本中是通过wait,notifyҎ实现的。该Ҏ也是通过底层在某个信号量上的d队列实现的。而UnsafecM直接提供操作pȝ调度命opark,unpark,减少信号量的开销Q提高新能?/p>

   从上面可以看出,UnsafecL通过提供底层的操作系l命令接口给开发者,从而提供程序的性能?/p>



abin 2015-03-15 23:42 发表评论
]]>javaq发库之Executors常用的创建ExecutorService的几个方法说?/title><link>http://www.aygfsteel.com/stevenjohn/archive/2015/01/21/422344.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Wed, 21 Jan 2015 14:18:00 GMT</pubDate><guid>http://www.aygfsteel.com/stevenjohn/archive/2015/01/21/422344.html</guid><wfw:comment>http://www.aygfsteel.com/stevenjohn/comments/422344.html</wfw:comment><comments>http://www.aygfsteel.com/stevenjohn/archive/2015/01/21/422344.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/stevenjohn/comments/commentRss/422344.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/stevenjohn/services/trackbacks/422344.html</trackback:ping><description><![CDATA[<p><strong>一、线E池的创?/strong> </p><p> 我们可以通过ThreadPoolExecutor来创Z个线E池?br /></p><pre>new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, milliseconds,runnableTaskQueue, handler);</pre><p>创徏一个线E池需要输入几个参敎ͼ </p><ul><li>corePoolSizeQ线E池的基本大)Q当提交一个Q务到U程池时Q线E池会创Z个线E来执行dQ即使其他空闲的基本U程能够执行CQ务也会创建线E,{到需要执行的d数大于线E池基本大小时就不再创徏。如果调用了U程池的prestartAllCoreThreadsҎQ线E池会提前创建ƈ启动所有基本线E?</li><li>runnableTaskQueueQQ务队列)Q用于保存等待执行的d的阻塞队列?可以选择以下几个d队列? <ul><li>ArrayBlockingQueueQ是一个基于数l结构的有界d队列Q此队列?FIFOQ先q先出)原则对元素进行排序?</li><li>LinkedBlockingQueueQ一个基于链表结构的d队列Q此队列按FIFO Q先q先出) 排序元素Q吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列?</li><li>SynchronousQueueQ一个不存储元素的阻塞队列。每个插入操作必ȝ到另一个线E调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueueQ静态工厂方法Executors.newCachedThreadPool使用了这个队列?</li><li>PriorityBlockingQueueQ一个具有优先的无限阻塞队列?</li></ul></li><li>maximumPoolSizeQ线E池最大大)Q线E池允许创徏的最大线E数。如果队列满了,q且已创建的U程数小于最大线E数Q则U程池会再创建新的线E执行Q务。值得注意的是如果使用了无界的d队列q个参数没什么效果?</li><li>ThreadFactoryQ用于设|创建线E的工厂Q可以通过U程工厂l每个创建出来的U程讄更有意义的名字?</li><li>RejectedExecutionHandlerQ饱和策略)Q当队列和线E池都满了,说明U程池处于饱和状态,那么必须采取一U策略处理提交的CQ务。这个策略默认情况下是AbortPolicyQ表C无法处理新d时抛出异常。以下是JDK1.5提供的四U策略? <ul><li>AbortPolicyQ直接抛出异常?</li><li>CallerRunsPolicyQ只用调用者所在线E来q行d?</li><li>DiscardOldestPolicyQ丢弃队列里最q的一个Q务,q执行当前Q务?</li><li>DiscardPolicyQ不处理Q丢弃掉?</li><li> 当然也可以根据应用场景需要来实现RejectedExecutionHandler接口自定义策略。如记录日志或持久化不能处理的Q务?</li></ul></li><li>keepAliveTimeQ线E活动保持时_Q线E池的工作线E空闲后Q保持存zȝ旉。所以如果Q务很多,q且每个d执行的时间比较短Q可以调大这个时_提高U程的利用率?</li><li>TimeUnitQ线E活动保持时间的单位Q:可选的单位有天QDAYSQ,时QHOURSQ,分钟QMINUTESQ,毫秒(MILLISECONDS)Q微U?MICROSECONDS, 千分之一毫秒)和毫微秒(NANOSECONDS, 千分之一微秒)?</li></ul><p> </p><p><strong>二、Executors提供了一些方便创建ThreadPoolExecutor的常用方法,主要有以下几个:</strong> </p><p><strong>1?nbsp;Executors.newFixedThreadPool(int nThreads);创徏固定大小(nThreads,大小不能过int的最大?的线E池</strong> </p><p>//U程数量 </p><p> int nThreads = 20; </p><p> //创徏executor 服务  </p><p>  ExecutorService executor = Executors.newFixedThreadPool(nThreads) ; </p><p>重蝲后的版本Q需要多传入实现?span style="font-family: monospace;">ThreadFactory接口的对象?/span> </p><p><span style="font-family: "sans serif", tahoma, verdana, helvetica;"> ExecutorService executor = </span>Executors. <span style="font-family: "sans serif", tahoma, verdana, helvetica;">newFixedThreadPool</span>(nThreads,<span style="font-family: monospace;">threadFactory);</span> </p><p>说明Q创建固定大?nThreads,大小不能过int的最大?的线E池Q缓冲Q务的队列为LinkedBlockingQueue,大小为整型的最大数Q当使用此线E池Ӟ在同执行的Q务数量超q传入的U程池大值后Q将会放入LinkedBlockingQueueQ在LinkedBlockingQueue中的d需要等待线E空闲后再执行,如果攑օLinkedBlockingQueue中的d过整型的最大数Ӟ抛出RejectedExecutionException?</p><p><strong>2、Executors.newSingleThreadExecutor()Q创建大ؓ1的固定线E池?/strong> </p><p> ExecutorService executor = Executors.newSingleThreadExecutor(); </p><p>重蝲后的版本Q需要多传入实现?span style="font-family: monospace;">ThreadFactory接口的对象?/span> </p><p><span style="font-family: "sans serif", tahoma, verdana, helvetica;"> ExecutorService executor = </span>Executors. newSingleThreadScheduledExecutor(ThreadFactory threadFactory)  </p><p>说明Q创建大ؓ1的固定线E池Q同时执行Q?task)的只有一?其它的(dQtask都放在LinkedBlockingQueue中排队等待执行?</p><p>3?strong>Executors</strong>.<strong>newCachedThreadPool</strong>()Q创建corePoolSize?Q最大线E数为整型的最大数Q线EkeepAliveTime?分钟Q缓存Q务的队列为SynchronousQueue的线E池?</p><p> ExecutorService executor = Executors.newCachedThreadPool()Q?</p><p> 当然也可以以下面的方式创建,重蝲后的版本Q需要多传入实现?span style="font-family: monospace;">ThreadFactory接口的对象?/span> </p><p><span style="font-family: "sans serif", tahoma, verdana, helvetica;"> ExecutorService executor = </span>Executors.newCachedThreadPool(ThreadFactory threadFactory) ; </p><p>说明Q用时Q放入线E池的taskd会复用线E或启动新线E来执行Q注意事:启动的线E数如果过整型最大值后会抛出RejectedExecutionException异常Q启动后的线E存zL间ؓ一分钟?</p><p><strong>4、Executors.newScheduledThreadPool(int corePoolSize):创徏corePoolSize大小的线E池?/strong> </p><p>//U程数量 </p><p> int corePoolSize= 20; </p><p> //创徏executor 服务  </p><p>  ExecutorService executor = Executors.newScheduledThreadPool(corePoolSize) ; </p><p>重蝲后的版本Q需要多传入实现?span style="font-family: monospace;">ThreadFactory接口的对象?/span> </p><p><span style="font-family: "sans serif", tahoma, verdana, helvetica;"> ExecutorService executor = Executors.</span><span style="font-family: "sans serif", tahoma, verdana, helvetica;">newScheduledThreadPool</span>(<span style="font-family: "sans serif", tahoma, verdana, helvetica;">corePoolSize</span>, threadFactory)<span style="font-family: "sans serif", tahoma, verdana, helvetica;"> Q?/span> </p><p> 说明Q线EkeepAliveTime?Q缓存Q务的队列为DelayedWorkQueueQ注意不要超q整型的最大倹{?/p><p><br /><br /><br /><br /><br /><br /></p><img src ="http://www.aygfsteel.com/stevenjohn/aggbug/422344.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/stevenjohn/" target="_blank">abin</a> 2015-01-21 22:18 <a href="http://www.aygfsteel.com/stevenjohn/archive/2015/01/21/422344.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank">ŷ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">۲</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ӣ</a>| <a href="http://" target="_blank">¯</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Դ</a>| <a href="http://" target="_blank">İ</a>| <a href="http://" target="_blank">˷</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʲ</a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ǭ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Խ</a>| <a href="http://" target="_blank">ͬ</a>| <a href="http://" target="_blank">᰸</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">۲</a>| <a href="http://" target="_blank">߰</a>| <a href="http://" target="_blank">ƽң</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>