﻿<?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-X-Spirit-随笔分类-Java SE</title><link>http://www.blogjava.net/zhangwei217245/category/43167.html</link><description>Always Beyond the Time</description><language>zh-cn</language><lastBuildDate>Sun, 16 Mar 2014 15:15:27 GMT</lastBuildDate><pubDate>Sun, 16 Mar 2014 15:15:27 GMT</pubDate><ttl>60</ttl><item><title>【Tech Details】【转】有关Java SPI机制</title><link>http://www.blogjava.net/zhangwei217245/archive/2012/03/03/410530.html</link><dc:creator>X-Spirit</dc:creator><author>X-Spirit</author><pubDate>Sat, 03 Mar 2012 03:34:00 GMT</pubDate><guid>http://www.blogjava.net/zhangwei217245/archive/2012/03/03/410530.html</guid><wfw:comment>http://www.blogjava.net/zhangwei217245/comments/410530.html</wfw:comment><comments>http://www.blogjava.net/zhangwei217245/archive/2012/03/03/410530.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangwei217245/comments/commentRss/410530.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangwei217245/services/trackbacks/410530.html</trackback:ping><description><![CDATA[@import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
<div><span style="font-family: Arial; line-height: 26px; background-color: #ffffff;"><br />
</span></div>
<span style="font-family: Arial; line-height: 26px; background-color: #ffffff;">
<div>转自：http://blog.csdn.net/fenglibing/article/details/7083071</div>
<div><span style="font-family: Arial; line-height: 26px; background-color: #ffffff;"><br />
</span></div>
一个服务(service)通常指的是已知的接口或者抽象类，服务提供方就是对这个接口或者抽象类的实现，然后按spi标准存放到资源路径META-INF/services目录下，文件的命名为该服务接口的全限定名。如有一个服务接口com.test.Service，其服务实现类为com.test.ChildService，那此时需要在META-INF/services中放置文件com.test.Service，其中的内容就为该实现类的全限定名com.test.ChildService，有多个服务实现，每一行写一个服务实现，#后面的内容为注释，并且该文件只能够是以UTF-8编码。</span><br style="font-family: Arial; line-height: 26px; background-color: #ffffff;" />
<span style="font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp; &nbsp; 这种实现方式，感觉和我们通常的开发方式差不多，都是定义一个接口，然后子类实现父类中定义的方法，为什么要搞这么一套标准以及单独搞一个配置文件？这种方式主要是针对不同的服务提供厂商，对不同场景的提供不同的解决方案制定的一套标准，举个简单的例子，如现在的JDK中有支持音乐播放，假设只支持mp3的播放，有些厂商想在这个基础之上支持mp4的播放，有的想支持mp5，而这些厂商都是第三方厂商，如果没有提供SPI这种实现标准，那就只有修改JAVA的源代码了，那这个弊端也是显而易见的，也就是不能够随着JDK的升级而升级现在的应用了，而有了SPI标准，SUN公司只需要提供一个播放接口，在实现播放的功能上通过ServiceLoad的方式加载服务，那么第三方只需要实现这个播放接口，再按SPI标准进行打包成jar，再放到classpath下面就OK了，没有一点代码的侵入性。</span><br style="font-family: Arial; line-height: 26px; background-color: #ffffff;" />
<p style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp; &nbsp; 以下是找到的几篇文章：</p>
<p style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp; &nbsp; 1、<a href="http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html" target="_blank" style="color: #ca0000; text-decoration: none;">http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html</a>，这个是官方的文档，有对service的详细介绍，包括规范以及一个简单的示例，这个是学习SPI必须看的文档；</p>
<p style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp; &nbsp; 注：<a href="http://docs.oracle.com/javase/1.4.2/docs/guide/jar/jar.html#Service%20Provider" style="color: #ca0000; text-decoration: none;">http://docs.oracle.com/javase/1.4.2/docs/guide/jar/jar.html#Service%20Provider</a>，这个是1.4中对Service Provider的介绍，加载服务是通过sun.misc.Service进行加载的，这个也有相应的示例，照做就OK；</p>
<p style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp; &nbsp; 2、Java的SPI机制：<a href="http://www.2cto.com/kf/201012/79868.html" target="_blank" style="color: #ca0000; text-decoration: none;">http://www.2cto.com/kf/201012/79868.html</a>，这个是国人写的一篇示例文章，也挺不错，里面也有一个简单的示例；</p>
<p style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp; &nbsp; 3、Developing a Service Provider using Java API(Service Provider Interface)：<a href="http://blog.csdn.net/fenglibing/article/details/7083526" style="color: #ca0000; text-decoration: none;">http://blog.csdn.net/fenglibing/article/details/7083526</a>，这篇文章是转的alexa发表在blogspot上面的，也是一个开发SPI的示例，有兴趣的也可以看看；</p>
<p style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp; &nbsp; 4、Add Mp3 capabilities to Java Sound with SPI：<a href="http://www.javaworld.com/javaworld/jw-11-2000/jw-1103-mp3.html" target="_blank" style="color: #ca0000; text-decoration: none;">http://www.javaworld.com/javaworld/jw-11-2000/jw-1103-mp3.html</a>，这是一个比较老的例子，基于jdk1.3的，因为在jdk1.3的时候还没有支持mp3格式，只支持AU, AIF, MIDI, and WAV等格式，也是一个值得参考的示例。</p>
<p style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp; &nbsp; 我这边也写了一个简单得不能够再简单的示例，源码可以这里下载：<a href="http://download.csdn.net/detail/fenglibing/3939882" style="color: #ca0000; text-decoration: none;">http://download.csdn.net/detail/fenglibing/3939882</a></p>
<p style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;"><br />
</p>
<p style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;"><br />
</p>
<p style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;"><br />
</p>
<p style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;">最后很重要一点：</p>
<p style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;"><br />
</p>
<p style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;">如果想要覆盖某个Provider，可以在对应的META-INF/services的配置文件中加上新service的一行，或者也可以写在另一个有依赖关系的jar包中，只要和原来的Provider命名不同即可。加载顺序上可以考虑使用@Priority注解来调整加载的优先级。</p>
<p style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;"><br />
</p>
<p style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;"><br />
</p>
@import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&amp;file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);<img src ="http://www.blogjava.net/zhangwei217245/aggbug/410530.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangwei217245/" target="_blank">X-Spirit</a> 2012-03-03 11:34 <a href="http://www.blogjava.net/zhangwei217245/archive/2012/03/03/410530.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【Effective】Logging最佳实践</title><link>http://www.blogjava.net/zhangwei217245/archive/2011/02/12/409787.html</link><dc:creator>X-Spirit</dc:creator><author>X-Spirit</author><pubDate>Sat, 12 Feb 2011 11:55:00 GMT</pubDate><guid>http://www.blogjava.net/zhangwei217245/archive/2011/02/12/409787.html</guid><wfw:comment>http://www.blogjava.net/zhangwei217245/comments/409787.html</wfw:comment><comments>http://www.blogjava.net/zhangwei217245/archive/2011/02/12/409787.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangwei217245/comments/commentRss/409787.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangwei217245/services/trackbacks/409787.html</trackback:ping><description><![CDATA[<div><div style="color: #000000; font-family: 微软雅黑; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;"><strong>#意识</strong></div> <p><strong style="color: #000000; font-family: 微软雅黑; font-size: 14px; font-style: normal; font-variant: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;"><span style="color: #0000ff; font-size: medium;">ASAP (As Soon As Possible)原则</span></strong></p> <div style="color: #000000; font-family: 微软雅黑; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;">当线上出现诡异问题，</div> <div style="color: #000000; font-family: 微软雅黑; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;">当你意识到靠现有的日志无法定位问题时，</div> <div style="color: #000000; font-family: 微软雅黑; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;">当现象难以在你的开发环境重现时，</div> <div style="color: #000000; font-family: 微软雅黑; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;">请不要执著于枯坐肉眼看代码，因为：一）不一定是你代码逻辑问题，可能是脏数据造成的，是老业务数据造成的，是分布式环境造成的，是其他子系统造成的；二）线上业务处于不稳定中，条件不允许问题定位无限期。</div> <div style="color: #000000; font-family: 微软雅黑; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;">此时，<strong>请立即在问题相关的调用链条上，一次性：</strong></div> <div style="color: #000000; font-family: 微软雅黑; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;"> <ul><li><strong>在函数的入口和出口打印日志，同时</strong><strong><span style="font-size: 10.5pt; font-family: 微软雅黑, sans-serif; color: red;">打印输入、输出参数</span></strong></li><li><strong>catch(){&#8230;&#8230;}里打印stacktrace，</strong><strong><span style="font-size: 10.5pt; font-family: 微软雅黑, sans-serif;">同时</span><span style="font-size: 10.5pt; font-family: 微软雅黑, sans-serif; color: red;">打印try块中关键变量的值（避免你发现某个异常是问题第一原因，却不知道是什么变量传入导致的）</span></strong></li><li><strong>与其他模块交互的接口入口处打印输入参数，</strong></li></ul> </div> 即，<strong>解决线上问题归根结底要靠log、a lot of log output！</strong><br /> <div>在logging的力度上切勿犹犹豫豫，我们的工程师习惯于吝啬地找两个函数打印日志、打包部署一把、没看出来、再找几个函数打印、再部署、等着现象重现再观察、&#8230;&#8230;，一来二去时间流逝，闲庭信步，从客服知道的小事故变成了全国皆知的大事故。</div> <div>所以，再强调一遍：<strong>在你的调用链条上，逐层调用的函数入口和出口都打印详细日志，不怕多只怕少，然后部署，等待现象重现，毕其功于一役！</strong></div> <div>&nbsp;</div> <div> <div><strong><span style="color: #0000ff; font-size: medium;">我们要记录什么？</span></strong></div> <div>1）完成某项操作所需的时间</div>    </div> <div> <p>通过它可以跟踪为什么系统响应变慢或者太快</p> <ul><li>处理完一个incoming request所耗费的时间，精确到毫秒</li><li>执行数据库查询的时间</li><li>从磁盘或者存储介质获取数据的时间</li><li>等等</li></ul>    </div> <div>2）异常和堆栈跟踪</div> <div>&nbsp;</div> <div>3）Sessions</div> <div>知道一个问题是由谁引起的非常重要，因此在日志中使用会话标识符就变得必不可少。它可以简单到是一个 IP 地址或者是一个更复杂的 UUID，只要能区分不同的请求者就足够。</div> <div>&nbsp;</div> <div>4）版本号</div> <div>&nbsp;</div> <div><strong>#工具</strong></div> <div><strong><span style="color: #0000ff; font-size: medium;">推荐的Java Logging框架</span></strong></div> <div>1）log4j：我们的配置是，log4j.appender.CONSOLE.layout.ConversionPattern= [%-d{yyyy-MM-dd HH\:mm\:ss.SSS}] [%p] [%c]  [%m]%n；%p是日志优先级，%c是类目名，%m是输出信息，%n是回车换行符。</div> <div>2）logback：log4j创建人Ceki G&#252;lc&#252;后续推出了SLF4J+logback。SLF4J(Simple Logging  Facade for Java)作为commons-logging的替代，为各种logging  APIs提供了一个简单的统一接口，使得最终用户能够在部署的时候配置所希望的logging  APIs的实现。logback胜在性能，据称&#8220;某些关键操作，比如判定是否记录一条日志语句的操作，其性能得到了显著的提高。这个操作在logback 中需要3纳秒，而在 log4j&nbsp;中则需要30纳 秒。 logback&nbsp;创建记录器（logger）的速度也更快：13毫秒，而在  log4j&nbsp;中需要23毫秒。更重要的是，它获取已存在的记录器只需94纳秒， 而  log4j&nbsp;需要2234纳秒，时间减少到了1/23。跟java.util.logging(JUL)相比性能提高也是显著的&#8221;。</div> <div>&nbsp;</div> <div><strong>#配置</strong></div> <div><strong><span style="color: #0000ff; font-size: medium;">不要随便从网上找一个log4j的配置文件，请确认你理解每一个配置项</span></strong></div> <div>我们既然输出日志，自然期望在面对&#8220;<strong>这个问题是否从过去几天开始出现？</strong>&#8221;这样的疑问时，不至于发现你的rollingPolicy错误设置导致只能看到最近几小时的日志，或者日志发生时间没有精确到毫秒。</div> <div>&nbsp;</div> <div> <div><strong>#理念</strong></div> <div><strong><span style="color: #0000ff; font-size: medium;">可用grep抽取的日志：独立的行！</span></strong></div> <div>我们总是希望能用grep处理日志文件。这意味着：<strong>一个日志条目永远不应该跨多行，除非你是堆栈打印</strong>。</div>    </div> <div>我们会用grep问日志什么问题呢？如：</div> <div> <ul><li>用手机号13910******下单的顾客最近三天内都来自于哪些IP？</li><li>浏览地址是****?from=kfapi的顾客，但referral却是搜索引擎域名，最近三天有多少次？</li><li>最近一周内，订单中心执行的所有事务，耗时最长的一次是多长时间？</li><li>&#215;&#215;&#215;&#215;的接口是否真的于18:00发送了一个请求，我们收到的参数是什么？</li></ul>    </div> <div>确保你的日志能回答这样的问题。</div> <div>&nbsp;</div> <div><strong><span style="color: #0000ff; font-size: medium;">不同关注领域写不同的日志文件</span></strong></div> <div>当访问和调用极其频繁，有时候你会发现把你的工程里什么信息都打印到一个日志文件里，会让你看得头昏脑胀。</div> <div>最简单的示范就是Apache的访问日志和错误日志是分开的。</div> <div>同样，你也可以把更加安静的事件（偶尔出现）与更加喧闹的事件分开存储。</div> <div>如，对外的开放平台可以打印三种日志文件：connection log（建立链接和关闭链接，附带接入参数），message log（内部调用链），stacktrace log（异常的堆栈打印）。</div> <div>&nbsp;</div> <div><strong>#具体实现</strong></div> <div> <div><strong><span style="color: #0000ff; font-size: medium;">至少精确到毫秒</span></strong></div> <div>日志必须包含时间戳，精确到至少毫秒级。</div>    </div> <div>如果只是记录到秒级，我们曾明知代码因缺乏并发控制而产生BUG，却只能郁闷地看着精确到秒级的日志。</div> <div>对Java来说，最好配置为：<span style="font-family: tahoma;">yyyy-MM-dd/HH:mm:ss<span style="background-color: yellow; color: #ff0000;">.SSS</span>。</span></div> <div>&nbsp;</div> <div> <div><strong><span style="color: #0000ff; font-size: medium;">请尽可能打印明确的会话标识</span></strong></div> <div>日志条目里打印一个会话标识（A certain session identifier），当有许多并发请求打过来时，你就能基于此字段过滤 client 了。比如，我们日志会补充打印一个浏览器 cookies 里种下的 UUID 。</div>    </div> <div>&nbsp;</div> <div><strong><span style="color: #0000ff; font-size: medium;">log4j的isDebugEnabled判断</span></strong></div> <div>如果打印信息是常量字符串或简单字符串拼接，那么不需要if ( log.isDebugEnabled() )。</div> <div>如果你拼装的动作比较耗资源，请用if ( log.isDebugEnabled() )。</div> <div>&nbsp;</div> <div> <div><strong><span style="color: #0000ff; font-size: medium;">如有可能，请将性能数据标准化输出</span></strong></div> <div>这样更方便grep或hadoop做性能数据抽取和挖掘，从而能很轻松地转换为图形监控。</div>    </div> <div>比如，订单中心的性能数据格式为：<strong>树枝标志&nbsp;当前节点起始时间 [当前节点持续时间, 当前节点自身消耗时间, 在父节点中所占的时间比例]</strong></div> <div>&nbsp;</div> <div> <div><strong><span style="color: #0000ff; font-size: medium;">哪些位置需要部署性能检测点&nbsp;</span></strong></div> <div>（1）访问数据库的dao层；</div> <div>（2）访问外部资源的ext层；</div> <div>（3）访问mq的方法；</div> <div>（4）等等，一切不在你自己负责的工程掌握的部分（外部），或一切你认为自己工程的性能危险点，都需要加入性能监控日志。</div>    </div> <div>&nbsp;</div> <div>&nbsp;</div> <div><strong>#Sample</strong></div> <div> <div><span style="color: #0000ff; font-size: medium;"><strong>一个好的启动日志</strong></span></div>    </div> <div><a href="http://www.cnblogs.com/zhengyun_ustc/" target="_blank"><img style="width: 709px;" src="http://images.cnblogs.com/cnblogs_com/zhengyun_ustc/255879/o_clipboard%20-013%20%E5%89%AF%E6%9C%AC.png" alt="http://images.cnblogs.com/cnblogs_com/zhengyun_ustc/255879/o_clipboard%20-013%20%E5%89%AF%E6%9C%AC.png" /></a></div> <div>打印了应用的版本号，客户端的会话标识，关键步骤的执行时长。</div> <div>&nbsp;</div> <div><strong style="color: #0000ff; font-size: medium;">一个好的堆栈跟踪日志</strong></div> <div><a href="http://www.cnblogs.com/zhengyun_ustc/" target="_blank"><img style="width: 709px;" src="http://images.cnblogs.com/cnblogs_com/zhengyun_ustc/255879/o_clipboard%20-%20014%E5%89%AF%E6%9C%AC.png" alt="http://images.cnblogs.com/cnblogs_com/zhengyun_ustc/255879/o_clipboard%20-%20014%E5%89%AF%E6%9C%AC.png" /></a></div></div><br /><br /><div>本文首发于<a href="http://www.cnblogs.com/zhengyun_ustc/" target="_blank">旁观者-郑昀</a>的<a href="http://www.cnblogs.com/zhengyun_ustc/category/438091.html" target="_blank">55最佳实践系列</a>，链接：<a href="http://www.cnblogs.com/zhengyun_ustc/archive/2012/12/15/logging_bp.html" target="_blank">http://www.cnblogs.com/zhengyun_ustc/archive/2012/12/15/logging_bp.html</a></div><img src ="http://www.blogjava.net/zhangwei217245/aggbug/409787.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangwei217245/" target="_blank">X-Spirit</a> 2011-02-12 19:55 <a href="http://www.blogjava.net/zhangwei217245/archive/2011/02/12/409787.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 多线程同步问题的探究（五、你有我有全都有—— ThreadLocal如何解决并发安全性？）【更新重要补疑】</title><link>http://www.blogjava.net/zhangwei217245/archive/2010/04/24/317651.html</link><dc:creator>X-Spirit</dc:creator><author>X-Spirit</author><pubDate>Sat, 24 Apr 2010 05:36:00 GMT</pubDate><guid>http://www.blogjava.net/zhangwei217245/archive/2010/04/24/317651.html</guid><wfw:comment>http://www.blogjava.net/zhangwei217245/comments/317651.html</wfw:comment><comments>http://www.blogjava.net/zhangwei217245/archive/2010/04/24/317651.html#Feedback</comments><slash:comments>15</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangwei217245/comments/commentRss/317651.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangwei217245/services/trackbacks/317651.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 前面我们介绍了Java当中多个线程抢占一个共享资源的问题。但不论是同步还是重入锁，都不能实实在在的解决资源紧缺的情况，这些方案只是靠制定规则来约束线程的行为，让它们不再拼命的争抢，而不是真正从实质上解决他们对资源的需求。在JDK 1.2当中，引入了java.lang.ThreadLocal。它为我们提供了一种全新的思路来解决线程并发的问题。但是他的名字难免让我们望文生义：本地线程？...&nbsp;&nbsp;<a href='http://www.blogjava.net/zhangwei217245/archive/2010/04/24/317651.html'>阅读全文</a><img src ="http://www.blogjava.net/zhangwei217245/aggbug/317651.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangwei217245/" target="_blank">X-Spirit</a> 2010-04-24 13:36 <a href="http://www.blogjava.net/zhangwei217245/archive/2010/04/24/317651.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 多线程同步问题的探究（四、协作，互斥下的协作——Java多线程协作（wait、notify、notifyAll））</title><link>http://www.blogjava.net/zhangwei217245/archive/2010/04/24/316526.html</link><dc:creator>X-Spirit</dc:creator><author>X-Spirit</author><pubDate>Sat, 24 Apr 2010 05:35:00 GMT</pubDate><guid>http://www.blogjava.net/zhangwei217245/archive/2010/04/24/316526.html</guid><wfw:comment>http://www.blogjava.net/zhangwei217245/comments/316526.html</wfw:comment><comments>http://www.blogjava.net/zhangwei217245/archive/2010/04/24/316526.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangwei217245/comments/commentRss/316526.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangwei217245/services/trackbacks/316526.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Java监视器支持两种线程：互斥和协作。前面我们介绍了采用对象锁和重入锁来实现的互斥。这一篇中，我们来看一看线程的协作。举个例子：有一家汉堡店举办吃汉堡比赛，决赛时有3个顾客来吃，3个厨师来做，一个服务员负责协调汉堡的数量。为了避免浪费，制作好的汉堡被放进一个能装有10个汉堡的长条状容器中，按照先进先出的原则取汉堡。如果容器被装满，则厨师停止做汉堡，如果顾客发现容器内的汉堡吃完了，...&nbsp;&nbsp;<a href='http://www.blogjava.net/zhangwei217245/archive/2010/04/24/316526.html'>阅读全文</a><img src ="http://www.blogjava.net/zhangwei217245/aggbug/316526.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangwei217245/" target="_blank">X-Spirit</a> 2010-04-24 13:35 <a href="http://www.blogjava.net/zhangwei217245/archive/2010/04/24/316526.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 多线程同步问题的探究（三、Lock来了，大家都让开【2. Fair or Unfair? It is a question...】）</title><link>http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315619.html</link><dc:creator>X-Spirit</dc:creator><author>X-Spirit</author><pubDate>Sat, 24 Apr 2010 05:34:00 GMT</pubDate><guid>http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315619.html</guid><wfw:comment>http://www.blogjava.net/zhangwei217245/comments/315619.html</wfw:comment><comments>http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315619.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangwei217245/comments/commentRss/315619.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangwei217245/services/trackbacks/315619.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315619.html'>阅读全文</a><img src ="http://www.blogjava.net/zhangwei217245/aggbug/315619.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangwei217245/" target="_blank">X-Spirit</a> 2010-04-24 13:34 <a href="http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315619.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 多线程同步问题的探究（三、Lock来了，大家都让开【1. 认识重入锁】）</title><link>http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315526.html</link><dc:creator>X-Spirit</dc:creator><author>X-Spirit</author><pubDate>Sat, 24 Apr 2010 05:33:00 GMT</pubDate><guid>http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315526.html</guid><wfw:comment>http://www.blogjava.net/zhangwei217245/comments/315526.html</wfw:comment><comments>http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315526.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangwei217245/comments/commentRss/315526.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangwei217245/services/trackbacks/315526.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315526.html'>阅读全文</a><img src ="http://www.blogjava.net/zhangwei217245/aggbug/315526.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangwei217245/" target="_blank">X-Spirit</a> 2010-04-24 13:33 <a href="http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315526.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 多线程同步问题的探究（二、给我一把锁，我能创造一个规矩）</title><link>http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315283.html</link><dc:creator>X-Spirit</dc:creator><author>X-Spirit</author><pubDate>Sat, 24 Apr 2010 05:32:00 GMT</pubDate><guid>http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315283.html</guid><wfw:comment>http://www.blogjava.net/zhangwei217245/comments/315283.html</wfw:comment><comments>http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315283.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangwei217245/comments/commentRss/315283.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangwei217245/services/trackbacks/315283.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315283.html'>阅读全文</a><img src ="http://www.blogjava.net/zhangwei217245/aggbug/315283.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangwei217245/" target="_blank">X-Spirit</a> 2010-04-24 13:32 <a href="http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315283.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java多线程同步问题的探究（一、线程的先来后到）</title><link>http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315080.html</link><dc:creator>X-Spirit</dc:creator><author>X-Spirit</author><pubDate>Sat, 24 Apr 2010 05:31:00 GMT</pubDate><guid>http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315080.html</guid><wfw:comment>http://www.blogjava.net/zhangwei217245/comments/315080.html</wfw:comment><comments>http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315080.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangwei217245/comments/commentRss/315080.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangwei217245/services/trackbacks/315080.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315080.html'>阅读全文</a><img src ="http://www.blogjava.net/zhangwei217245/aggbug/315080.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangwei217245/" target="_blank">X-Spirit</a> 2010-04-24 13:31 <a href="http://www.blogjava.net/zhangwei217245/archive/2010/04/24/315080.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【Effective】JVM 调优参数说明</title><link>http://www.blogjava.net/zhangwei217245/archive/2010/03/16/411107.html</link><dc:creator>X-Spirit</dc:creator><author>X-Spirit</author><pubDate>Tue, 16 Mar 2010 14:42:00 GMT</pubDate><guid>http://www.blogjava.net/zhangwei217245/archive/2010/03/16/411107.html</guid><wfw:comment>http://www.blogjava.net/zhangwei217245/comments/411107.html</wfw:comment><comments>http://www.blogjava.net/zhangwei217245/archive/2010/03/16/411107.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangwei217245/comments/commentRss/411107.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangwei217245/services/trackbacks/411107.html</trackback:ping><description><![CDATA[@import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);
<div style="color: #333333; font-family: verdana, sans-serif; font-size: 13px; line-height: 17px; background-color: #ffffff;">&nbsp;内部服务参数配置：</div>
<span style="color: #333333; font-family: verdana, sans-serif; font-size: 13px; line-height: 17px; background-color: #ffffff;">JAVA_OPTS="-server -XX:+UseParNewGC -Xms1024m -Xmx2048m -XX:MaxNewSize=128m -XX:NewSize=128m -XX:PermSize=96m -XX:MaxPermSize=128m -XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:CMSInitiatingOccupancyFraction=1 -XX:+CMSIncrementalMode -XX:MaxTenuringThreshold=0 -XX:SurvivorRatio=20000 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 &nbsp;-XX:CMSIncrementalDutyCycleMin=10 -XX:CMSIncrementalDutyCycle=30 -XX:CMSMarkStackSize=8M -XX:CMSMarkStackSizeMax=32M"</span><br style="color: #333333; font-family: verdana, sans-serif; font-size: 13px; line-height: 17px; background-color: #ffffff;" />
<br style="color: #333333; font-family: verdana, sans-serif; font-size: 13px; line-height: 17px; background-color: #ffffff;" />
<span style="color: #333333; font-family: verdana, sans-serif; font-size: 13px; line-height: 17px; background-color: #ffffff;">前端应用参数配置：</span><br style="color: #333333; font-family: verdana, sans-serif; font-size: 13px; line-height: 17px; background-color: #ffffff;" />
<div style="color: #333333; font-family: verdana, sans-serif; font-size: 13px; line-height: 17px; background-color: #ffffff;">&nbsp;JAVA_OPTS="-server&nbsp;&nbsp;-Xmx4096m&nbsp;-Xms4096m&nbsp;-Xmn480m&nbsp;-Xss256k&nbsp;-XX:PermSize=128m&nbsp;-XX:MaxPermSize=256m&nbsp;-XX:+UseConcMarkSweepGC&nbsp;-XX:ParallelGCThreads=8&nbsp;-XX:CMSFullGCsBeforeCompaction=0&nbsp;<br />
-XX:+UseCMSCompactAtFullCollection&nbsp;-XX:SurvivorRatio=8&nbsp;-XX:MaxTenuringThreshold=7&nbsp;-XX:GCTimeRatio=19&nbsp;<br />
-Xnoclassgc&nbsp;-XX:+DisableExplicitGC&nbsp;-XX:+UseParNewGC&nbsp;-XX:-CMSParallelRemarkEnabled&nbsp;-XX:CMSInitiatingOccupancyFraction=70&nbsp;-XX:SoftRefLRUPolicyMSPerMB=0"&nbsp;</div>
<br style="color: #333333; font-family: verdana, sans-serif; font-size: 13px; line-height: 17px; background-color: #ffffff;" />
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;">参数说明：</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-Xmx1280m</strong>：设置JVM最大可用内存为1280m。最大可设为3550m。具体应用可适当调整。</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-Xms1280m</strong>：设置JVM初始内存为1280m。此值可以设置与-Xmx相同，以避免每次垃圾回收完成后JVM重新分配内存。</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-Xmn480m</strong>：设置年轻代大小为480m。整个堆大小=年轻代大小 + 年老代大小 + 持久代大小。持久代一般固定大小为64m，所以增大年轻代后，将会减小年老代大小。此值对系统性能影响较大，Sun官方推荐配置为整个堆的3/8。</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-Xss256k</strong>：设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M，以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。在相同物理内存下，减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的，不能无限生成，经验值在3000~5000左右。</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-XX:PermSize=64m</strong>：指定 jvm 中 Perm Generation 的最小值。 这个参数需要看你的实际情况。可以通过jmap 命令看看到底需要多少。</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-XX:MaxPermSize=128m</strong>：指定 Perm Generation 的最大值</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-XX:+UseConcMarkSweepGC</strong><strong>：</strong>设置并发收集器</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-XX:ParallelGCThreads=8</strong><strong>：</strong>配置并行收集器的线程数，即：同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-XX:CMSFullGCsBeforeCompaction=0</strong><strong>：</strong>由于并发收集器不对内存空间进行压缩、整理，所以运行一段时间以后会产生&#8220;碎片&#8221;，使得运行效率降低。此值设置运行多少次GC以后对内存空间进行压缩、整理。</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-XX:+UseCMSCompactAtFullCollection</strong><strong>：</strong>打开对年老代的压缩。可能会影响性能，但是可以消除碎片。</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-XX:SurvivorRatio=8</strong><strong>：</strong>每个survivor space 和 eden之间的比例。</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-XX:MaxTenuringThreshold=7</strong><strong>：</strong>设置垃圾最大年龄。如果设置为0的话，则年轻代对象不经过Survivor区，直接进入年老代。对于年老代比较多的应用，可以提高效率。如果将此值设置为一个较大值，则年轻代对象会在Survivor区进行多次复制，这样可以增加对象再年轻代的存活时间，增加在年轻代即被回收的概率。</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-XX:GCTimeRatio=19</strong><strong>：</strong>设置垃圾回收时间占程序运行时间的百分比，公式为1/(1+n)。</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-Xnoclassgc</strong><strong>：</strong>禁用类垃圾回收，性能会有一定提高。</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-XX:+DisableExplicitGC</strong><strong>：</strong>当此参数打开时，在程序中调用System.gc()将会不起作用。默认是off。</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-XX:+UseParNewGC</strong><strong>：</strong>设置年轻代为并行收集。可与CMS收集同时使用。</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-XX:-CMSParallelRemarkEnabled</strong><strong>：</strong>在使用 UseParNewGC 的情况下 , 尽量减少 mark 的时间。</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-XX:CMSInitiatingOccupancyFraction=70</strong><strong>：</strong>指示在 old generation 在使用了 70% 的比例后 , 启动 concurrent collector。</p>
<p style="color: #333333; font-size: 13px; line-height: 17px; background-color: #ffffff; padding: 0px; margin-bottom: 10px; font-family: Arial, Helvetica, FreeSans, sans-serif;"><strong>-XX:SoftRefLRUPolicyMSPerMB=0</strong><strong>：</strong>每兆堆空闲空间中SoftReference的存活时间。</p>
@import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&amp;file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);<img src ="http://www.blogjava.net/zhangwei217245/aggbug/411107.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangwei217245/" target="_blank">X-Spirit</a> 2010-03-16 22:42 <a href="http://www.blogjava.net/zhangwei217245/archive/2010/03/16/411107.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>