﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-少年阿宾-随笔分类-concurrent</title><link>http://www.blogjava.net/stevenjohn/category/54681.html</link><description>那些青春的岁月</description><language>zh-cn</language><lastBuildDate>Tue, 14 Jun 2016 14:05:19 GMT</lastBuildDate><pubDate>Tue, 14 Jun 2016 14:05:19 GMT</pubDate><ttl>60</ttl><item><title>聊聊高并发系统之限流特技-1</title><link>http://www.blogjava.net/stevenjohn/archive/2016/06/14/430882.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Tue, 14 Jun 2016 05:38:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2016/06/14/430882.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/430882.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2016/06/14/430882.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/430882.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/430882.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在开发高并发系统时有三把利器用来保护系统：缓存、降级和限流。缓存的目的是提升系统访问速度和增大系统能处理的容量，可谓是抗高并发流量的银弹；而降级是当服务出问题或者影响到核心流程的性能则需要暂时屏蔽掉，待高峰或者问题解决后再打开；而有些场景并不能用缓存和降级来解决，比如稀缺资源（秒杀、抢购）、写服务（如评论、下单）、频繁的复杂查询（评论的最后几页），因此需有一种手段来限制这些场景的并发/请求量，即限...&nbsp;&nbsp;<a href='http://www.blogjava.net/stevenjohn/archive/2016/06/14/430882.html'>阅读全文</a><img src ="http://www.blogjava.net/stevenjohn/aggbug/430882.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2016-06-14 13:38 <a href="http://www.blogjava.net/stevenjohn/archive/2016/06/14/430882.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于单CPU，多CPU上的原子操作</title><link>http://www.blogjava.net/stevenjohn/archive/2015/04/20/424546.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Mon, 20 Apr 2015 06:02:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2015/04/20/424546.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/424546.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2015/04/20/424546.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/424546.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/424546.html</trackback:ping><description><![CDATA[<span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">所谓原子操作,就是"不可中断的一个或一系列操作" 。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">硬件级的原子操作：</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">在单处理器系统(UniProcessor)中，能够在单条指令中完成的操作都可以认为是" 原子操作"，因为中断只能发生于指令之间。这也是某些CPU指令系统中引入了test_and_set、test_and_clear等指令用于临界资源互斥的原因。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">在对称多处理器(Symmetric Multi-Processor)结构中就不同了，由于系统中有多个处理器在独立地运行，即使能在单条指令中完成的操作也有可能受到干扰。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">在x86 平台上，CPU提供了在指令执行期间对总线加锁的手段。CPU芯片上有一条引线#HLOCK pin，如果汇编语言的程序中在一条指令前面加上前缀"LOCK"，经过汇编以后的机器代码就使CPU在执行这条指令的时候把#HLOCK pin的电位拉低，持续到这条指令结束时放开，从而把总线锁住，这样同一总线上别的CPU就暂时不能通过总线访问内存了，保证了这条指令在多处理器环境中的</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">原子性。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">软件级的原子操作：</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">软件级的原子操作实现依赖于硬件原子操作的支持。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">对于linux而言，内核提供了两组原子操作接口：一组是针对整数进行操作；另一组是针对单独的位进行操作。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">2.1. 原子整数操作</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">针对整数的原子操作只能对atomic_t类型的数据处理。这里没有使用C语言的int类型，主要是因为：</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">1) 让原子函数只接受atomic_t类型操作数，可以确保原子操作只与这种特殊类型数据一起使用</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">2) 使用atomic_t类型确保编译器不对相应的值进行访问优化</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">3) 使用atomic_t类型可以屏蔽不同体系结构上的数据类型的差异。尽管Linux支持的所有机器上的整型数据都是32位，但是使用atomic_t的代码只能将该类型的数据当作24位来使用。这个限制完全是因为在SPARC体系结构上，原子操作的实现不同于其它体系结构：32位int类型的低8位嵌入了一个锁，因为SPARC体系结构对原子操作缺乏指令级的支持，所以只能利用该锁来避免对原子类型数据的并发访问。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">原子整数操作最常见的用途就是实现计数器。原子整数操作列表在中定义。原子操作通常是内敛函数，往往通过内嵌汇编指令来实现。如果某个函数本来就是原子的，那么它往往会被定义成一个宏。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">在编写内核时，操作也简单：</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">atomic_t use_cnt;</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">atomic_set(&amp;use_cnt, 2);</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">atomic_add(4, &amp;use_cnt);</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">atomic_inc(use_cnt);</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">2.2. 原子性与顺序性</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">原子性确保指令执行期间不被打断，要么全部执行，要么根本不执行。而顺序性确保即使两条或多条指令出现在独立的执行线程中，甚至独立的处理器上，它们本该执行的顺序依然要保持。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">2.3. 原子位操作</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">原子位操作定义在文件中。令人感到奇怪的是位操作函数是对普通的内存地址进行操作的。原子位操作在多数情况下是对一个字长的内存访问，因而位号该位于0-31之间(在64位机器上是0-63之间),但是对位号的范围没有限制。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">编写内核代码，只要把指向了你希望的数据的指针给操作函数，就可以进行位操作了：</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">unsigned long word = 0;</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">set_bit(0, &amp;word); /*第0位被设置*/</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">set_bit(1, &amp;word); /*第1位被设置*/</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">clear_bit(1, &amp;word); /*第1位被清空*/</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">change_bit(0, &amp;word); /*翻转第0位*/</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">为什么关注原子操作？</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">1）在确认一个操作是原子的情况下，多线程环境里面，我们可以避免仅仅为保护这个操作在外围加上性能开销昂贵的锁。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">2）借助于原子操作，我们可以实现互斥锁。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">3）借助于互斥锁，我们可以把一些列操作变为原子操作。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">GNU C中x++是原子操作吗？</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">答案不是。x++由3条指令完成。x++在单CPU下不是原子操作。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">对应3条汇编指令</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">movl x, %eax</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">addl $1, %eax</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">movl %eax, x</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">在vc2005下对应</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">++x;</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">004232FA mov eax,dword ptr [x]</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">004232FD add eax,1</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">00423300 mov dword ptr [x],eax</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">仍然是3条指令。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">所以++x，x++等都不是原子操作。因其步骤包括了从内存中取x值放入寄存器，加寄存器，把值写入内存三个指令。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">如何实现x++的原子性？</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">在单处理器上，如果执行x++时，禁止多线程调度，就可以实现原子。因为单处理的多线程并发是伪并发。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">在多处理器上，需要借助cpu提供的Lock功能。锁总线。读取内存值，修改，写回内存三步期间禁止别的CPU访问总线。同时我估计使用Lock指令锁总线的时候，OS也不会把当前线程调度走了。要是调走了，那就麻烦了。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">在多处理器系统中存在潜在问题的原因是：</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">不使用LOCK指令前缀锁定总线的话，在一次内存访问周期中有可能其他处理器会产生异常或中断，而在异常处理中有可能会修改尚未写入的地址，这样当INC操作完成后会产生无效数据（覆盖了前面的修改）。</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">spinlock 用于CPU同步, 它的实现是基于CPU锁定数据总线的指令.</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">当某个CPU锁住数据总线后, 它读一个内存单元(spinlock_t)来判断这个spinlock 是否已经被别的CPU锁住. 如果否, 它写进一个特定值, 表示锁定成功, 然后返回. 如果是, 它会重复以上操作直到成功, 或者spin次数超过一个设定值. 锁定数据总线的指令只能保证一个机器指令内, CPU独占数据总线.</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">单CPU当然能用spinlock, 但实现上无需锁定数据总线.</span><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><br style="box-sizing: border-box; color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;" /><span style="color: #666666; font-family: Arial, SimHei, SimSun, 宋体, Tahoma, Helvetica, sans-serif; line-height: 16.799999237060547px;">spinlock在锁定的时候,如果不成功,不会睡眠,会持续的尝试,单cpu的时候spinlock会让其它process动不了.</span><img src ="http://www.blogjava.net/stevenjohn/aggbug/424546.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2015-04-20 14:02 <a href="http://www.blogjava.net/stevenjohn/archive/2015/04/20/424546.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sun.misc.Unsafe</title><link>http://www.blogjava.net/stevenjohn/archive/2015/03/15/423475.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Sun, 15 Mar 2015 15:42:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2015/03/15/423475.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/423475.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2015/03/15/423475.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/423475.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/423475.html</trackback:ping><description><![CDATA[&nbsp; &nbsp; &nbsp;在看 Java并发包(java.util.concurrent)中大量使用了CAS操作，CAS即 Compare And Swap(CAS)，比较并交换，其中由sun.misc.Unsafe实现，Unsafe类提供了硬件级别的原子操作，Java无法直接访问到操作系统底层（如系统硬件等)，为此Java使用native方法来扩展Java程序的功能。具体实现使用c++。       牛B，**Unsafe类提供了硬件级别的原子操作**，但到底是什么意思呢？CAS从字面意思上就有两部分：1、读取并比较；2、判断并决定是否交换。然后把这两步骤作为原子操作，这样就能保证线程安全<br />&nbsp; &nbsp; &nbsp;几句关于<em>Unsafe</em>的并发性。compareAndSwap方法是<em>原子</em>的,并且可用来实现高性能的、无锁的数据结构。比如,考虑问题:在使用大量线程的共享对象上增长值。...<br />&nbsp; &nbsp; &nbsp;Java是一门安全的编程语言，防止程序员犯很多愚蠢的错误，它们大部分是基于内存管理的。但是，有一种方式可以有意的执行一些不安全、容易犯错的操作，那就是使用<code>Unsafe</code>类。<br />&nbsp; &nbsp; CAS操作有3个操作数，内存值M，预期值E，新值U，如果M==E，则将内存值修改为B，否则啥都不做。<br />&nbsp; &nbsp;&nbsp;<span style="color: #993300;">sun.misc.Unsafe</span>这个类是如此地不安全，以至于JDK开发者增加了很多特殊限制来访问它。它的构造器是私有的，工厂方法<span style="color: #993300;">getUnsafe()</span>的调用器只能被Bootloader加载。如你在下面代码片段的第8行所见，这个家伙甚至没有被任何类加载器加载，所以它的类加载器是<span style="color: #993300;">null</span>。它会抛出<span style="color: #993300;">SecurityException</span> 异常来阻止侵入者。<br />&nbsp; &nbsp; public final class Unsafe {<div>&nbsp; &nbsp;...</div><div>&nbsp; &nbsp;private Unsafe() {}</div><div>&nbsp; &nbsp;private static final Unsafe theUnsafe = new Unsafe();</div><div>&nbsp; &nbsp;...</div><div>&nbsp; &nbsp;public static Unsafe getUnsafe() {</div><div>&nbsp; &nbsp; &nbsp; Class cc = sun.reflect.Reflection.getCallerClass(2);</div><div>&nbsp; &nbsp; &nbsp; if (cc.getClassLoader() != null)</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new SecurityException("Unsafe");</div><div>&nbsp; &nbsp; &nbsp; return theUnsafe;</div><div>&nbsp; &nbsp;}</div><div>&nbsp; &nbsp;...</div><div>}<br />幸运的是这里有一个Unsafe的变量可以被用来取得Unsafe的实例。我们可以轻松地编写一个复制方法通过反射来实现，如下所示：<br /> （<a href="http://highlyscalable.wordpress.com/2012/02/02/direct-memory-access-in-java/" target="_blank" rel="nofollow">http://highlyscalable.wordpress.com/2012/02/02/direct-memory-access-in-java/</a>）</div><div><div number1="" index0=""  alt2"=""><code keyword"="">public</code> <code keyword"="">static</code> <code plain"="">Unsafe getUnsafe() {</code></div><div number2="" index1=""  alt1"=""><code spaces"="">&nbsp;&nbsp;&nbsp;</code><code keyword"="">try</code> <code plain"="">{</code></div><div number3="" index2=""  alt2"=""><code spaces"="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code plain"="">Field f = Unsafe.</code><code keyword"="">class</code><code plain"="">.getDeclaredField(</code><code string"="">"theUnsafe"</code><code plain"="">);</code></div><div number4="" index3=""  alt1"=""><code spaces"="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code plain"="">f.setAccessible(</code><code keyword"="">true</code><code plain"="">);</code></div><div number5="" index4=""  alt2"=""><code spaces"="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code keyword"="">return</code> <code plain"="">(Unsafe)f.get(</code><code keyword"="">null</code><code plain"="">);</code></div><div number6="" index5=""  alt1"=""><code spaces"="">&nbsp;&nbsp;&nbsp;</code><code plain"="">} </code><code keyword"="">catch</code> <code plain"="">(Exception e) { </code></div><div number7="" index6=""  alt2"=""><code spaces"="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code comments"="">/* ... */</code></div><div number8="" index7=""  alt1"=""><code spaces"="">&nbsp;&nbsp;&nbsp;</code><code plain"="">}</code></div><div number9="" index8=""  alt2"=""><code plain"="">}<br /></code></div></div><p><strong>Unsafe一些有用的特性</strong></p><ol><li>虚拟机&#8220;集约化&#8221;（VM intrinsification）：如用于无锁Hash表中的CAS（比较和交换）。再比如<span style="color: #993300;">compareAndSwapInt</span>这个方法用JNI调用，包含了对CAS有特殊引导的本地代码。在这里你能读到更多关于CAS的信息：<a href="http://en.wikipedia.org/wiki/Compare-and-swap" target="_blank" rel="nofollow">http://en.wikipedia.org/wiki/Compare-and-swap</a>。</li><li>主机虚拟机（<em>译注：主机虚拟机主要用来管理其他虚拟机。而虚拟平台我们看到只有guest VM</em>）的<span style="color: #993300;">sun.misc.Unsafe</span>功能能够被用于未初始化的对象分配内存（用<span style="color: #993300;">allocateInstance</span>方法），然后将构造器调用解释为其他方法的调用。</li><li>你可以从本地内存地址中追踪到这些数据。使用<span style="color: #993300;">java.lang.Unsafe</span>类获取内存地址是可能的。而且可以通过unsafe方法直接操作这些变量！</li><li>使用<span style="color: #993300;">allocateMemory</span>方法，内存可以被分配到堆外。例如当<span style="color: #993300;">allocateDirect</span>方法被调用时<span style="color: #993300;">DirectByteBuffer</span>构造器内部会使用<span style="color: #993300;">allocateMemory</span>。</li><li><span style="color: #993300;">arrayBaseOffset</span>和<span style="color: #993300;">arrayIndexScale</span>方法可以被用于开发arraylets，一种用来将大数组分解为小对象、限制扫描的实时消耗或者在大对象上做更新和移动。</li></ol><p>Unsafe.java是jdk并发类库java.util.concurrent包中使用的底层类，该类中的方法都是通过native方法调用操作系统命令。</p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr> 在多线程环境下，主要存在两种特殊的场景：</p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>1；多个线程同时访问某个对象的方法，由于操作系统对线程调度的不确定性，存在使该对象的状态处于不一致的状态，为了避免这种情况的发生，我们可以声明该方法为同步方法（synchronized）。保证某一时刻只有一个线程调用该方法，其它调用线程则被阻塞。这种方法在并发性很高的情况下会产生大量的线程调度开销。从而影响程序的并发性能。在java.util.concurrent包中通过使用非阻塞原子方法，减少操作系统的无用线程调度开销，从而提高并发性能。</p> <p>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>2；多线程通过某个对象进行通信，即常见的生产者消费者模型。在以前的jdk版本中是通过wait,notify方法实现的。该方法也是通过底层在某个信号量上的阻塞队列实现的。而Unsafe类中直接提供操作系统调度命令park,unpark,减少信号量的开销，提高新能。</p> <p>&nbsp;<wbr>&nbsp;<wbr> 从上面可以看出，Unsafe类是通过提供底层的操作系统命令接口给开发者，从而提供程序的性能。</p><br /><br /><img src ="http://www.blogjava.net/stevenjohn/aggbug/423475.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2015-03-15 23:42 <a href="http://www.blogjava.net/stevenjohn/archive/2015/03/15/423475.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java并发库之Executors常用的创建ExecutorService的几个方法说明</title><link>http://www.blogjava.net/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.blogjava.net/stevenjohn/archive/2015/01/21/422344.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/422344.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2015/01/21/422344.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/422344.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/422344.html</trackback:ping><description><![CDATA[<p><strong>一、线程池的创建</strong> </p><p> 我们可以通过ThreadPoolExecutor来创建一个线程池。<br /></p><pre>new  ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, milliseconds,runnableTaskQueue, handler);</pre><p>创建一个线程池需要输入几个参数： </p><ul><li>corePoolSize（线程池的基本大小）：当提交一个任务到线程池时，线程池会创建一个线程来执行任务，即使其他空闲的基本线程能够执行新任务也会创建线程，等到需要执行的任务数大于线程池基本大小时就不再创建。如果调用了线程池的prestartAllCoreThreads方法，线程池会提前创建并启动所有基本线程。 </li><li>runnableTaskQueue（任务队列）：用于保存等待执行的任务的阻塞队列。 可以选择以下几个阻塞队列。    <ul><li>ArrayBlockingQueue：是一个基于数组结构的有界阻塞队列，此队列按 FIFO（先进先出）原则对元素进行排序。 </li><li>LinkedBlockingQueue：一个基于链表结构的阻塞队列，此队列按FIFO （先进先出） 排序元素，吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列。 </li><li>SynchronousQueue：一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作，否则插入操作一直处于阻塞状态，吞吐量通常要高于LinkedBlockingQueue，静态工厂方法Executors.newCachedThreadPool使用了这个队列。 </li><li>PriorityBlockingQueue：一个具有优先级的无限阻塞队列。 </li></ul></li><li>maximumPoolSize（线程池最大大小）：线程池允许创建的最大线程数。如果队列满了，并且已创建的线程数小于最大线程数，则线程池会再创建新的线程执行任务。值得注意的是如果使用了无界的任务队列这个参数就没什么效果。 </li><li>ThreadFactory：用于设置创建线程的工厂，可以通过线程工厂给每个创建出来的线程设置更有意义的名字。 </li><li>RejectedExecutionHandler（饱和策略）：当队列和线程池都满了，说明线程池处于饱和状态，那么必须采取一种策略处理提交的新任务。这个策略默认情况下是AbortPolicy，表示无法处理新任务时抛出异常。以下是JDK1.5提供的四种策略。    <ul><li>AbortPolicy：直接抛出异常。 </li><li>CallerRunsPolicy：只用调用者所在线程来运行任务。 </li><li>DiscardOldestPolicy：丢弃队列里最近的一个任务，并执行当前任务。 </li><li>DiscardPolicy：不处理，丢弃掉。 </li><li> 当然也可以根据应用场景需要来实现RejectedExecutionHandler接口自定义策略。如记录日志或持久化不能处理的任务。 </li></ul></li><li>keepAliveTime（线程活动保持时间）：线程池的工作线程空闲后，保持存活的时间。所以如果任务很多，并且每个任务执行的时间比较短，可以调大这个时间，提高线程的利用率。 </li><li>TimeUnit（线程活动保持时间的单位）：可选的单位有天（DAYS），小时（HOURS），分钟（MINUTES），毫秒(MILLISECONDS)，微秒(MICROSECONDS, 千分之一毫秒)和毫微秒(NANOSECONDS, 千分之一微秒)。 </li></ul><p>&nbsp;</p><p><strong>二、Executors提供了一些方便创建ThreadPoolExecutor的常用方法，主要有以下几个：</strong> </p><p><strong>1、&nbsp;Executors.newFixedThreadPool(int nThreads);创建固定大小(nThreads,大小不能超过int的最大值)的线程池</strong> </p><p>//线程数量 </p><p>&nbsp;int&nbsp;nThreads = 20; </p><p> //创建executor&nbsp;服务&nbsp; </p><p> &nbsp;ExecutorService executor = Executors.newFixedThreadPool(nThreads) ; </p><p>重载后的版本，需要多传入实现了<span style="font-family: monospace;">ThreadFactory接口的对象。</span> </p><p><span style="font-family: &quot;sans serif&quot;, tahoma, verdana, helvetica;">&nbsp;ExecutorService executor =&nbsp;</span>Executors.&nbsp;<span style="font-family: &quot;sans serif&quot;, tahoma, verdana, helvetica;">newFixedThreadPool</span>(nThreads,<span style="font-family: monospace;">threadFactory);</span> </p><p>说明：创建固定大小(nThreads,大小不能超过int的最大值)的线程池，缓冲任务的队列为LinkedBlockingQueue,大小为整型的最大数，当使用此线程池时，在同执行的任务数量超过传入的线程池大小值后，将会放入LinkedBlockingQueue，在LinkedBlockingQueue中的任务需要等待线程空闲后再执行，如果放入LinkedBlockingQueue中的任务超过整型的最大数时，抛出RejectedExecutionException。 </p><p><strong>2、Executors.newSingleThreadExecutor()：创建大小为1的固定线程池。</strong> </p><p>&nbsp;ExecutorService executor = Executors.newSingleThreadExecutor(); </p><p>重载后的版本，需要多传入实现了<span style="font-family: monospace;">ThreadFactory接口的对象。</span> </p><p><span style="font-family: &quot;sans serif&quot;, tahoma, verdana, helvetica;">&nbsp;ExecutorService executor =&nbsp;</span>Executors.&nbsp;newSingleThreadScheduledExecutor(ThreadFactory&nbsp;threadFactory)&nbsp; </p><p>说明：创建大小为1的固定线程池，同时执行任务(task)的只有一个,其它的（任务）task都放在LinkedBlockingQueue中排队等待执行。 </p><p>3、<strong>Executors</strong>.<strong>newCachedThreadPool</strong>()；创建corePoolSize为0，最大线程数为整型的最大数，线程keepAliveTime为1分钟，缓存任务的队列为SynchronousQueue的线程池。 </p><p>&nbsp;ExecutorService executor = Executors.newCachedThreadPool()； </p><p> 当然也可以以下面的方式创建，重载后的版本，需要多传入实现了<span style="font-family: monospace;">ThreadFactory接口的对象。</span> </p><p><span style="font-family: &quot;sans serif&quot;, tahoma, verdana, helvetica;">&nbsp;ExecutorService executor =&nbsp;</span>Executors.newCachedThreadPool(ThreadFactory&nbsp;threadFactory)&nbsp;; </p><p>说明：使用时，放入线程池的task任务会复用线程或启动新线程来执行，注意事项：启动的线程数如果超过整型最大值后会抛出RejectedExecutionException异常，启动后的线程存活时间为一分钟。 </p><p><strong>4、Executors.newScheduledThreadPool(int corePoolSize):创建corePoolSize大小的线程池。</strong> </p><p>//线程数量 </p><p>&nbsp;int&nbsp;corePoolSize= 20; </p><p> //创建executor&nbsp;服务&nbsp; </p><p> &nbsp;ExecutorService executor = Executors.newScheduledThreadPool(corePoolSize) ; </p><p>重载后的版本，需要多传入实现了<span style="font-family: monospace;">ThreadFactory接口的对象。</span> </p><p><span style="font-family: &quot;sans serif&quot;, tahoma, verdana, helvetica;">&nbsp;ExecutorService executor = Executors.</span><span style="font-family: &quot;sans serif&quot;, tahoma, verdana, helvetica;">newScheduledThreadPool</span>(<span style="font-family: &quot;sans serif&quot;, tahoma, verdana, helvetica;">corePoolSize</span>,&nbsp;threadFactory)<span style="font-family: &quot;sans serif&quot;, tahoma, verdana, helvetica;">&nbsp;；</span> </p><p> 说明：线程keepAliveTime为0，缓存任务的队列为DelayedWorkQueue，注意不要超过整型的最大值。</p><p><br /><br /><br /><br /><br /><br /></p><img src ="http://www.blogjava.net/stevenjohn/aggbug/422344.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2015-01-21 22:18 <a href="http://www.blogjava.net/stevenjohn/archive/2015/01/21/422344.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>