﻿<?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-java路，自己走-随笔分类-java.thread</title><link>http://www.blogjava.net/syniii/category/47167.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 15 Dec 2010 21:18:09 GMT</lastBuildDate><pubDate>Wed, 15 Dec 2010 21:18:09 GMT</pubDate><ttl>60</ttl><item><title>[引]Java 5|6 并发包介绍</title><link>http://www.blogjava.net/syniii/archive/2010/12/08/340084.html</link><dc:creator>杨罗罗</dc:creator><author>杨罗罗</author><pubDate>Wed, 08 Dec 2010 09:40:00 GMT</pubDate><guid>http://www.blogjava.net/syniii/archive/2010/12/08/340084.html</guid><wfw:comment>http://www.blogjava.net/syniii/comments/340084.html</wfw:comment><comments>http://www.blogjava.net/syniii/archive/2010/12/08/340084.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/syniii/comments/commentRss/340084.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/syniii/services/trackbacks/340084.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: java.util.concurrent 包含许多线程安全、测试良好、高性能的并发构建块。不客气地说，创建 java.util.concurrent 的目的就是要实现 Collection 框架对数据结构所执行的并发操作。通过提供一组可靠的、高性能并发构建块，开发人员可以提高并发类的线程安全、可伸缩性、性能、可读性和可靠性。如果一些类名看起来相似，可能是因为 java.util.concurr...&nbsp;&nbsp;<a href='http://www.blogjava.net/syniii/archive/2010/12/08/340084.html'>阅读全文</a><img src ="http://www.blogjava.net/syniii/aggbug/340084.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/syniii/" target="_blank">杨罗罗</a> 2010-12-08 17:40 <a href="http://www.blogjava.net/syniii/archive/2010/12/08/340084.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多线程锁机制的总结</title><link>http://www.blogjava.net/syniii/archive/2010/12/03/339679.html</link><dc:creator>杨罗罗</dc:creator><author>杨罗罗</author><pubDate>Fri, 03 Dec 2010 02:11:00 GMT</pubDate><guid>http://www.blogjava.net/syniii/archive/2010/12/03/339679.html</guid><wfw:comment>http://www.blogjava.net/syniii/comments/339679.html</wfw:comment><comments>http://www.blogjava.net/syniii/archive/2010/12/03/339679.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/syniii/comments/commentRss/339679.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/syniii/services/trackbacks/339679.html</trackback:ping><description><![CDATA[<span style="font-family: Arial; font-size: 14px; line-height: 21px; ">AQS中有一个state字段（int类型，32位）用来描述有多少线程获持有锁。在独占锁的时代这个值通常是0或者1（如果是重入的就是重入的次数），在共享锁的时代就是持有锁的数量。<br />
自旋等待适合于比较短的等待，而挂起线程比较适合那些比较耗时的等待。<br />
<br />
<p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; margin-bottom: 14px; "><strong><font size="4">锁竞争</font></strong></p>
<p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; margin-bottom: 14px; ">影响锁竞争性的条件有两个：锁被请求的频率和每次持有锁的时间。显然当而这二者都很小的时候，锁竞争不会成为主要的瓶颈。但是如果锁使用不当，导致二者都比较大，那么很有可能CPU不能有效的处理任务，任务被大量堆积。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; margin-bottom: 14px; ">所以减少锁竞争的方式有下面三种：</p>
<ol>
    <li>减少锁持有的时间</li>
    <li>减少锁请求的频率</li>
    <li>采用共享锁取代独占锁</li>
</ol>
<div>
<p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; margin-bottom: 14px; "><font size="4"><strong>死锁</strong></font></p>
<p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; margin-bottom: 14px; ">1.一种情况是线程A永远不释放锁，结果B一直拿不到锁，所以线程B就&#8220;死掉&#8221;了<br />
2.第二种情况下，线程A拥有线程B需要的锁Y，同时线程B拥有线程A需要的锁X，那么这时候线程A/B互相依赖对方释放锁，于是二者都&#8220;死掉&#8221;了。<br />
3.如果一个线程总是不能被调度，那么等待此线程结果的线程可能就死锁了。这种情况叫做线程饥饿死锁。比如说非公平锁中，如果某些线程非常活跃，在高并发情况下这类线程可能总是拿到锁，那么那些活跃度低的线程可能就一直拿不到锁，这样就发生了&#8220;饥饿死&#8221;。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; margin-bottom: 14px; ">避免死锁的解决方案是：<br />
1.尽可能的按照锁的使用规范请求锁，另外锁的请求粒度要小（不要在不需要锁的地方占用锁，锁不用了尽快释放）；<br />
2.在高级锁里面总是使用tryLock或者定时机制（就是指定获取锁超时的时间，如果时间到了还没有获取到锁那么就放弃）。高级锁（Lock）里面的这两种方式可以有效的避免死锁。</p>
</div>
</span>
<img src ="http://www.blogjava.net/syniii/aggbug/339679.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/syniii/" target="_blank">杨罗罗</a> 2010-12-03 10:11 <a href="http://www.blogjava.net/syniii/archive/2010/12/03/339679.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]CAS原理</title><link>http://www.blogjava.net/syniii/archive/2010/11/18/338387.html</link><dc:creator>杨罗罗</dc:creator><author>杨罗罗</author><pubDate>Thu, 18 Nov 2010 07:16:00 GMT</pubDate><guid>http://www.blogjava.net/syniii/archive/2010/11/18/338387.html</guid><wfw:comment>http://www.blogjava.net/syniii/comments/338387.html</wfw:comment><comments>http://www.blogjava.net/syniii/archive/2010/11/18/338387.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/syniii/comments/commentRss/338387.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/syniii/services/trackbacks/338387.html</trackback:ping><description><![CDATA[<span style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: medium Simsun; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px;"><span style="line-height: 21px; font-family: Arial; font-size: 14px"><font size="4"><strong><span style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: medium Simsun; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px;"><span style="line-height: 21px; font-family: Arial; font-size: 14px">
<p style="margin: 0px 0px 14px">在JDK 5之前Java语言是靠synchronized关键字保证同步的，这会导致有锁（后面的章节还会谈到锁）。</p>
<p style="margin: 0px 0px 14px">锁机制存在以下问题：</p>
<p style="margin: 0px 0px 14px">（1）在多线程竞争下，加锁、释放锁会导致比较多的上下文切换和调度延时，引起性能问题。</p>
<p style="margin: 0px 0px 14px">（2）一个线程持有锁会导致其它所有需要此锁的线程挂起。</p>
<p style="margin: 0px 0px 14px">（3）如果一个优先级高的线程等待一个优先级低的线程释放锁会导致优先级倒置，引起性能风险。</p>
<p style="margin: 0px 0px 14px">volatile是不错的机制，但是volatile不能保证原子性。因此对于同步最终还是要回到锁机制上来。</p>
</span></span></strong></font>
<p style="margin: 0px 0px 14px"><font size="4"><strong><span style="color: red">独占锁是一种悲观锁，synchronized就是一种独占锁</span>，会导致其它所有需要锁的线程挂起，等待持有锁的线程释放锁。而另一个更加有效的锁就是乐观锁。所谓<span style="color: red">乐<span style="color: red">观锁就是，</span></span><span style="color: red">每次不加锁而是假设没有冲突而去完成某项操作，如果因为冲突失败就重试，直到成功为止。<br />
<br />
</span>CAS 操作</strong></font></p>
<p style="margin: 0px 0px 14px">上面的乐观锁用到的机制就是CAS，Compare and Swap。</p>
<p style="margin: 0px 0px 14px">CAS有3个操作数，内存值V，旧的预期值A，要修改的新值B。当且仅当预期值A和内存值V相同时，将内存值V修改为B，否则什么都不做。</p>
<p style="margin: 0px 0px 14px"><strong>非阻塞算法 （nonblocking algorithms）</strong></p>
<blockquote style="border-left: rgb(204,204,204) 18px solid; padding-bottom: 4px; border-right-width: 0px; background-color: rgb(238,238,238); margin: 0px; padding-left: 4px; width: 742px; padding-right: 4px; border-top-width: 0px; border-bottom-width: 0px; padding-top: 4px">
<p style="margin: 0px 0px 14px">一个线程的失败或者挂起不应该影响其他线程的失败或挂起的算法。</p>
</blockquote>
<p style="margin: 0px 0px 14px">现代的CPU提供了特殊的指令，可以自动更新共享数据，而且能够检测到其他线程的干扰，而 compareAndSet() 就用这些代替了锁定。</p>
<p style="margin: 0px 0px 14px">拿出AtomicInteger来研究在没有锁的情况下是如何做到数据正确性的。</p>
<blockquote style="border-left: rgb(204,204,204) 18px solid; padding-bottom: 4px; border-right-width: 0px; background-color: rgb(238,238,238); margin: 0px; padding-left: 4px; width: 742px; padding-right: 4px; border-top-width: 0px; border-bottom-width: 0px; padding-top: 4px">
<p style="margin: 0px 0px 14px">private volatile int value;</p>
</blockquote>
<p style="margin: 0px 0px 14px">首先毫无以为，<span style="color: red">在没有锁的机制下可能需要借助volatile原语，保证线程间的数据是可见的（共享的）。</span>这样才获取变量的值的时候才能直接读取。</p>
<blockquote style="border-left: rgb(204,204,204) 18px solid; padding-bottom: 4px; border-right-width: 0px; background-color: rgb(238,238,238); margin: 0px; padding-left: 4px; width: 742px; padding-right: 4px; border-top-width: 0px; border-bottom-width: 0px; padding-top: 4px">
<p style="margin: 0px 0px 14px">public final int get() {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return value;<br />
&nbsp;&nbsp;&nbsp; }</p>
</blockquote>
<p style="margin: 0px 0px 14px">然后来看看++i是怎么做到的。</p>
<blockquote style="border-left: rgb(204,204,204) 18px solid; padding-bottom: 4px; border-right-width: 0px; background-color: rgb(238,238,238); margin: 0px; padding-left: 4px; width: 742px; padding-right: 4px; border-top-width: 0px; border-bottom-width: 0px; padding-top: 4px">
<p style="margin: 0px 0px 14px">public final int incrementAndGet() {<br />
&nbsp;&nbsp;&nbsp; for (;;) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int current = get();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int next = current + 1;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (compareAndSet(current, next))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return next;<br />
&nbsp;&nbsp;&nbsp; }<br />
}</p>
</blockquote>
<p style="margin: 0px 0px 14px">在这里采用了CAS操作，每次从内存中读取数据然后将此数据和+1后的结果进行CAS操作，如果成功就返回结果，否则重试直到成功为止。</p>
<p style="margin: 0px 0px 14px">而compareAndSet利用JNI来完成CPU指令的操作。</p>
<blockquote style="border-left: rgb(204,204,204) 18px solid; padding-bottom: 4px; border-right-width: 0px; background-color: rgb(238,238,238); margin: 0px; padding-left: 4px; width: 742px; padding-right: 4px; border-top-width: 0px; border-bottom-width: 0px; padding-top: 4px">
<p style="margin: 0px 0px 14px">public final boolean compareAndSet(int expect, int update) {&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span><br />
&nbsp;&nbsp;&nbsp; return unsafe.compareAndSwapInt(this, valueOffset, expect, update);<br />
&nbsp;&nbsp;&nbsp; }</p>
</blockquote>
<p style="margin: 0px 0px 14px">整体的过程就是这样子的，利用CPU的CAS指令，同时借助JNI来完成Java的非阻塞算法。其它原子操作都是利用类似的特性完成的。</p>
<p style="margin: 0px 0px 14px">而整个J.U.C都是建立在CAS之上的，因此对于synchronized阻塞算法，J.U.C在性能上有了很大的提升。<br />
<br />
CAS看起来很爽，但是会导致&#8220;<strong>ABA问题</strong>&#8221;。</p>
<p style="margin: 0px 0px 14px">CAS算法实现一个重要前提需要取出内存中某时刻的数据，而在下时刻比较并替换，那么在这个<span style="color: red">时间差类会导致数据的变化</span>。</p>
<p style="margin: 0px 0px 14px">比如说一个线程one从内存位置V中取出A，这时候另一个线程two也从内存中取出A，并且two进行了一些操作变成了B，然后two又将V位置的数据变成A，这时候线程one进行CAS操作发现内存中仍然是A，然后one操作成功。尽管线程one的CAS操作成功，但是不代表这个过程就是没有问题的。如果链表的头在变化了两次后恢复了原值，但是不代表链表就没有变化。因此前面提到的<span style="color: red">原子操作</span><span style="color: red">AtomicStampedReference/AtomicMarkableReference就很有用了。这允许一对变化的元素进行原子操作。</span></p>
</span></span>
<img src ="http://www.blogjava.net/syniii/aggbug/338387.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/syniii/" target="_blank">杨罗罗</a> 2010-11-18 15:16 <a href="http://www.blogjava.net/syniii/archive/2010/11/18/338387.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>volatile的适用场景</title><link>http://www.blogjava.net/syniii/archive/2010/11/18/338382.html</link><dc:creator>杨罗罗</dc:creator><author>杨罗罗</author><pubDate>Thu, 18 Nov 2010 06:45:00 GMT</pubDate><guid>http://www.blogjava.net/syniii/archive/2010/11/18/338382.html</guid><wfw:comment>http://www.blogjava.net/syniii/comments/338382.html</wfw:comment><comments>http://www.blogjava.net/syniii/archive/2010/11/18/338382.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/syniii/comments/commentRss/338382.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/syniii/services/trackbacks/338382.html</trackback:ping><description><![CDATA[<span style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: medium Simsun; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px;" ><span style="line-height: 21px; font-family: Arial; font-size: 14px" ><span style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: medium Simsun; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px;" ><span style="line-height: 21px; font-family: Arial; font-size: 14px" >
<p style="margin: 0px 0px 14px"><span style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: medium Simsun; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(0,0,0); word-spacing: 0px;" ><span style="line-height: 21px; font-family: Arial; font-size: 14px" >volatile保证线程间的数据是可见的（共享的），但不保证数据同步</span></span><br />
<br />
volatile相当于synchronized的弱实现，也就是说volatile实现了类似synchronized的语义，却又没有锁机制。它确保对volatile字段的更新以可预见的方式告知其他的线程。<br />
volatile包含以下语义：<br />
（1）Java 存储模型不会对valatile指令的操作进行重排序：这个保证对volatile变量的操作时按照指令的出现顺序执行的。<br />
（2）volatile变量不会被缓存在寄存器中（只有拥有线程可见）或者其他对CPU不可见的地方，每次总是从主存中读取volatile变量的结果。也就是说对于volatile变量的修改，其它线程总是可见的，并且不是使用自己线程栈内部的变量。也就是在happens-before法则中，对一个valatile变量的写操作后，其后的任何读操作理解可见此写操作的结果。<br />
<br />
volatile变量的特性不错，但是volatile并不能保证线程安全的，也就是说volatile字段的操作不是原子性的，volatile变量只能保证可见性（一个线程修改后其它线程能够理解看到此变化后的结果），要想保证原子性，目前为止只能加锁！<br />
<br />
volatile通常在下面的场景：</p>
<div style="padding-bottom: 4px; background-color: rgb(238,238,238); padding-left: 4px; width: 909px; padding-right: 5px; font-size: 13px; border-left-color: rgb(204,204,204); word-break: break-all; padding-top: 4px"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" /><span style="color: rgb(0,0,255)">volatile</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">boolean</span><span style="color: rgb(0,0,0)"><span class="Apple-converted-space">&nbsp;</span>done<span class="Apple-converted-space">&nbsp;</span></span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">false</span><span style="color: rgb(0,0,0)">;<br />
<img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" /><br />
<img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" />&#8230;<br />
<img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" /><br />
<img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" id="Codehighlighter1_54_83_Open_Image" onclick="this.style.display='none'; Codehighlighter1_54_83_Open_Text.style.display='none'; Codehighlighter1_54_83_Closed_Image.style.display='inline'; Codehighlighter1_54_83_Closed_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" />&nbsp;&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span></span><span style="color: rgb(0,0,255)">while</span><span style="color: rgb(0,0,0)">(<span class="Apple-converted-space">&nbsp;</span></span><span style="color: rgb(0,0,0)">!</span><span style="color: rgb(0,0,0)"><span class="Apple-converted-space">&nbsp;</span>done )</span><span id="Codehighlighter1_54_83_Open_Text"><span style="color: rgb(0,0,0)">{<br />
<img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dosomething();<br />
<img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="" align="top" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" />&nbsp;&nbsp;&nbsp; }</span></span></div>
<p style="margin: 0px 0px 14px">&nbsp;应用volatile变量的三个原则：</p>
<blockquote style="border-left: rgb(204,204,204) 18px solid; padding-bottom: 4px; border-right-width: 0px; background-color: rgb(238,238,238); margin: 0px; padding-left: 4px; width: 742px; padding-right: 4px; border-top-width: 0px; border-bottom-width: 0px; padding-top: 4px">
<p style="margin: 0px 0px 14px">（1）写入变量不依赖此变量的值，或者只有一个线程修改此变量</p>
<p style="margin: 0px 0px 14px">（2）变量的状态不需要与其它变量共同参与不变约束</p>
<p style="margin: 0px 0px 14px">（3）访问变量不需要加锁</p>
</blockquote></span></span>
</span></span>
<img src ="http://www.blogjava.net/syniii/aggbug/338382.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/syniii/" target="_blank">杨罗罗</a> 2010-11-18 14:45 <a href="http://www.blogjava.net/syniii/archive/2010/11/18/338382.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]JAVA内存模型：happens-before法则</title><link>http://www.blogjava.net/syniii/archive/2010/11/18/338381.html</link><dc:creator>杨罗罗</dc:creator><author>杨罗罗</author><pubDate>Thu, 18 Nov 2010 06:42:00 GMT</pubDate><guid>http://www.blogjava.net/syniii/archive/2010/11/18/338381.html</guid><wfw:comment>http://www.blogjava.net/syniii/comments/338381.html</wfw:comment><comments>http://www.blogjava.net/syniii/archive/2010/11/18/338381.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/syniii/comments/commentRss/338381.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/syniii/services/trackbacks/338381.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: JMM规范：&nbsp;The rules for happens-before are:&nbsp;Program order rule. Each action in a thread happens-before every action in that thread that comes later in the program order.&nbsp;...&nbsp;&nbsp;<a href='http://www.blogjava.net/syniii/archive/2010/11/18/338381.html'>阅读全文</a><img src ="http://www.blogjava.net/syniii/aggbug/338381.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/syniii/" target="_blank">杨罗罗</a> 2010-11-18 14:42 <a href="http://www.blogjava.net/syniii/archive/2010/11/18/338381.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>