<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Open your thoughts</title>
	<atom:link href="http://blog.baturu.com/index.php/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.baturu.com</link>
	<description>James Gosling is not on the Java road any more !</description>
	<lastBuildDate>Fri, 20 Aug 2010 02:33:20 +0000</lastBuildDate>
	<language>zh-cn</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
	
<!-- Start Of Script Generated By WP-PostViews Plus -->
<script type='text/javascript' src='http://blog.baturu.com/wp-includes/js/jquery/jquery.js?ver=1.4.2'></script>
<script type="text/javascript">
/* <![CDATA[ */
/* ]]> */
</script>
<!-- End Of Script Generated By WP-PostViews Plus -->
	<item>
		<title>定制 xmlbeans 所生成的 package</title>
		<link>http://blog.baturu.com/index.php/2010/08/15/customize_java_packages_generated_by_xmlbeans.html</link>
		<comments>http://blog.baturu.com/index.php/2010/08/15/customize_java_packages_generated_by_xmlbeans.html#comments</comments>
		<pubDate>Sun, 15 Aug 2010 09:29:14 +0000</pubDate>
		<dc:creator>javafuns</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[schema]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.baturu.com/?p=1258</guid>
		<description><![CDATA[xmlbeans 也是 XML binding 工具之一，不了解的同学可以去了解一下，是这方面比较流行的框架之一。本篇不会长篇累牍的去介绍如何使用，相信在这方面，官方文档已足够。
我们知道，xmlbeans 提供了命令行工具，同时也有 ant task，支持把 xsd 生成 Java class 这一功能。xmlbeans 所生成的这些 classes 的 package 其实是有一定规律的。默认情况下，package 是根据 namespace 和元素类型而定。在某些情况下，特别是这个 xsd 并不是我们所能控制的情形下，我们需要生成不同于 namespace 的 package，这时就需要我们做出一些特殊处理。]]></description>
			<content:encoded><![CDATA[<p>xmlbeans 也是 XML binding 工具之一，不了解的同学可以去了解一下，是这方面比较流行的框架之一。本篇不会长篇累牍的去介绍如何使用，相信在这方面，官方文档已足够。</p>
<p>我们知道，xmlbeans 提供了命令行工具，同时也有 ant task，支持把 xsd 生成 Java class 这一功能。xmlbeans 所生成的这些 classes 的 package 其实是有一定规律的。默认情况下，package 是根据 namespace 和元素类型而定。在某些情况下，特别是这个 xsd 并不是我们所能控制的情形下，我们需要生成不同于 namespace 的 package，这时就需要我们做出一些特殊处理。</p>
<p>命令行：<code>scomp -d ..\classes -src ..\src -javasource 1.5 EasyPO.xsd po.xsdconfig</code></p>
<p>ant task：﻿</p>
<pre name="code" class="xml">
<taskdef name="xmlbeans" classname="org.apache.xmlbeans.impl.tool.XMLBean" classpathref="project.class.path"/>
<xmlbeans schema="${basedir}/EasyPO.xsd" destfile="${basedir}/po.jar"
                 classpathref="project.class.path" javasource="6"
                 failonerror="false" quiet="true">
</xmlbeans>
</pre>
<p>注意，在 ant task 下，只需要把 po.xsdconfig 放在与 EasyPO.xsd 同一目录即可。</p>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>2009/03/01 -- <a href="http://blog.baturu.com/index.php/2009/03/01/how-to-validate-xml-in-java-applications.html" title="Java 程序中如何对 XML 文档进行验证？">Java 程序中如何对 XML 文档进行验证？</a></li><li>2009/07/23 -- <a href="http://blog.baturu.com/index.php/2009/07/23/whats_the_purpose_of_schemalocation_attribute_in_xml.html" title="XML 中的 schemaLocation 属性究竟是什么意思？">XML 中的 schemaLocation 属性究竟是什么意思？</a></li><li>2009/07/07 -- <a href="http://blog.baturu.com/index.php/2009/07/07/which-style-of-wsdl-should-i-use-reship.html" title="Which style of WSDL should I use? (reship)">Which style of WSDL should I use? (reship)</a></li><li>2009/05/15 -- <a href="http://blog.baturu.com/index.php/2009/05/15/assign_default_schema_for_db2_in_hibernate.html" title="HIBERNATE－为DB2指定默认schema">HIBERNATE－为DB2指定默认schema</a></li><li>2009/03/02 -- <a href="http://blog.baturu.com/index.php/2009/03/02/whats-usage-of-xml-standalone.html" title="关于 XML standalone 的解释">关于 XML standalone 的解释</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.baturu.com/index.php/2010/08/15/customize_java_packages_generated_by_xmlbeans.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>卜算子 七夕</title>
		<link>http://blog.baturu.com/index.php/2010/08/15/busuanzi_qixi.html</link>
		<comments>http://blog.baturu.com/index.php/2010/08/15/busuanzi_qixi.html#comments</comments>
		<pubDate>Sun, 15 Aug 2010 02:25:58 +0000</pubDate>
		<dc:creator>javafuns</dc:creator>
				<category><![CDATA[My Life]]></category>
		<category><![CDATA[MyLife]]></category>

		<guid isPermaLink="false">http://blog.baturu.com/?p=1249</guid>
		<description><![CDATA[清晨被一群喜鹊吵醒了，一想这不是到七夕了吗，遂有感而发，也将这首词送与普天下的有情人。
同时祝愿舟曲的人们早日找到自己的家人和朋友，重建生活，也愿逝者安息。]]></description>
			<content:encoded><![CDATA[<p>清晨被一群喜鹊吵醒了，一想这不是到七夕了吗，遂有感而发，也将这首词送与普天下的有情人。<br />
同时祝愿舟曲的人们早日找到自己的家人和朋友，重建生活，也愿逝者安息。</p>
<p>窗外鹊群聊，<br />
缘是七夕到。<br />
织女天河欲见郎，<br />
犹待天桥造。</p>
<p>桌角企鹅弹，<br />
情侣来相叫。<br />
纵使相隔万里遥，<br />
仍见(现)情人笑。</p>
<p>附上：<br />
* (仄)仄仄平平，(仄)仄平平仄。(仄)仄平平仄仄平，(仄)仄平平仄。<br />
* (仄)仄仄平平，(仄)仄平平仄。(仄)仄平平仄仄平，(仄)仄平平仄。</p>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>2010/01/24 -- <a href="http://blog.baturu.com/index.php/2010/01/24/my_blog_is_recovered_once_again.html" title="本博客终于又重新启用了">本博客终于又重新启用了</a></li><li>2009/06/13 -- <a href="http://blog.baturu.com/index.php/2009/06/13/give_up_yahoo_stat.html" title="弃用 Yahoo! stat.">弃用 Yahoo! stat.</a></li><li>2009/01/08 -- <a href="http://blog.baturu.com/index.php/2009/01/08/new-zhangyusheng-in-mainland.html" title="内地&#8217;张羽&#8217;生">内地&#8217;张羽&#8217;生</a></li><li>2008/07/05 -- <a href="http://blog.baturu.com/index.php/2008/07/05/just-for-laughs.html" title="开心一笑">开心一笑</a></li><li>2008/06/14 -- <a href="http://blog.baturu.com/index.php/2008/06/14/european-cup-holand-vs-france-4-1.html" title="欧洲杯，荷兰4:1狂胜法国">欧洲杯，荷兰4:1狂胜法国</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.baturu.com/index.php/2010/08/15/busuanzi_qixi.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get the fast mirror of ubuntu server</title>
		<link>http://blog.baturu.com/index.php/2010/08/09/get_the_fast_mirror_of_ubuntu_server.html</link>
		<comments>http://blog.baturu.com/index.php/2010/08/09/get_the_fast_mirror_of_ubuntu_server.html#comments</comments>
		<pubDate>Mon, 09 Aug 2010 09:58:14 +0000</pubDate>
		<dc:creator>javafuns</dc:creator>
				<category><![CDATA[Operation Systems]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://blog.baturu.com/?p=1244</guid>
		<description><![CDATA[目前只支持 Ubuntu 10.04 LTS (Lucid Lynx ) 。]]></description>
			<content:encoded><![CDATA[<p>摘自：<a href="http://wowubuntu.com/get_fast_apt.html">http://wowubuntu.com/get_fast_apt.html</a></p>
<p>目前只支持 Ubuntu 10.04 LTS (Lucid Lynx ) 。</p>
<p># 命令：</p>
<p>选择最快的镜像服务器</p>
<blockquote><p>sudo wget -O /etc/apt/sources.list <a href="http://ubuntu9.com/topmirror/sourceslist/topfast">http://ubuntu9.com/topmirror/sourceslist/topfast</a></p></blockquote>
<p>选择你地域内 (国家) 的最快的镜像服务器</p>
<blockquote><p>sudo wget -O /etc/apt/sources.list <a href="http://ubuntu9.com/topmirror/sourceslist/topnear">http://ubuntu9.com/topmirror/sourceslist/topnear</a></p></blockquote>
<p>选择最稳定的镜像服务器</p>
<blockquote><p>sudo wget -O /etc/apt/sources.list <a href="http://ubuntu9.com/topmirror/sourceslist/topstable">http://ubuntu9.com/topmirror/sourceslist/topstable</a></p></blockquote>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>2010/02/22 -- <a href="http://blog.baturu.com/index.php/2010/02/22/dock_any_applications_into_system_tray_in_ubuntu.html" title="Dock any applications into system tray area in ubuntu">Dock any applications into system tray area in ubuntu</a></li><li>2009/06/30 -- <a href="http://blog.baturu.com/index.php/2009/06/30/svn_1-6_on_ubuntu.html" title="SVN 1.6 on ubuntu">SVN 1.6 on ubuntu</a></li><li>2009/06/19 -- <a href="http://blog.baturu.com/index.php/2009/06/19/how_to_reset_your_root_password.html" title="How to reset your Linux root password (reship)">How to reset your Linux root password (reship)</a></li><li>2009/05/13 -- <a href="http://blog.baturu.com/index.php/2009/05/13/how-to-install-libstdcso5-for-ubuntu.html" title="How to install libstdc++.so.5 for Ubuntu">How to install libstdc++.so.5 for Ubuntu</a></li><li>2010/08/05 -- <a href="http://blog.baturu.com/index.php/2010/08/05/integrate_your_shell_with_your_nautilus.html" title="Integrate your shell with your nautilus">Integrate your shell with your nautilus</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.baturu.com/index.php/2010/08/09/get_the_fast_mirror_of_ubuntu_server.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Integrate your shell with your nautilus</title>
		<link>http://blog.baturu.com/index.php/2010/08/05/integrate_your_shell_with_your_nautilus.html</link>
		<comments>http://blog.baturu.com/index.php/2010/08/05/integrate_your_shell_with_your_nautilus.html#comments</comments>
		<pubDate>Thu, 05 Aug 2010 13:32:24 +0000</pubDate>
		<dc:creator>javafuns</dc:creator>
				<category><![CDATA[Operation Systems]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Shell]]></category>

		<guid isPermaLink="false">http://blog.baturu.com/?p=1242</guid>
		<description><![CDATA[今天在安装反编译工具 JD-GUI 时，发现 ubuntu 提供了这样一个好玩的小玩意儿，可以将 shell 集成到 nautilus 中，这样可以随时随地在 nautilus 中右键打开 shell。]]></description>
			<content:encoded><![CDATA[<p>今天在安装反编译工具 JD-GUI 时，发现 ubuntu 提供了这样一个好玩的小玩意儿，可以将 shell 集成到 nautilus 中，这样可以随时随地在 nautilus 中右键打开 shell。</p>
<p>将 shell 脚本如 hello.sh 放到 ~/.gnome2/nautilus-scripts/ 目录下，然后你随意打开一个文件夹，展开右键菜单，赫然发现菜单中多了个 &#8220;脚本&#8221; 菜单项，其下一级菜单项就包含了刚才的 &#8220;hello.sh&#8221;。</p>
<p>好玩吧？ 那就赶紧动手试试吧！</p>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>2010/08/09 -- <a href="http://blog.baturu.com/index.php/2010/08/09/get_the_fast_mirror_of_ubuntu_server.html" title="Get the fast mirror of ubuntu server">Get the fast mirror of ubuntu server</a></li><li>2010/07/26 -- <a href="http://blog.baturu.com/index.php/2010/07/26/delete_files_in_batch_in_linux.html" title="Linux批量删除文件">Linux批量删除文件</a></li><li>2010/02/22 -- <a href="http://blog.baturu.com/index.php/2010/02/22/dock_any_applications_into_system_tray_in_ubuntu.html" title="Dock any applications into system tray area in ubuntu">Dock any applications into system tray area in ubuntu</a></li><li>2009/11/03 -- <a href="http://blog.baturu.com/index.php/2009/11/03/issue_that_java_swing_blank_on_some_linux_distribution.html" title="某些 Linux distribution 导致 Java swing 空白">某些 Linux distribution 导致 Java swing 空白</a></li><li>2009/06/30 -- <a href="http://blog.baturu.com/index.php/2009/06/30/svn_1-6_on_ubuntu.html" title="SVN 1.6 on ubuntu">SVN 1.6 on ubuntu</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.baturu.com/index.php/2010/08/05/integrate_your_shell_with_your_nautilus.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A brief introduction of what is RDF</title>
		<link>http://blog.baturu.com/index.php/2010/08/04/a_brief_introduction_of_whats_rdf.html</link>
		<comments>http://blog.baturu.com/index.php/2010/08/04/a_brief_introduction_of_whats_rdf.html#comments</comments>
		<pubDate>Wed, 04 Aug 2010 06:25:22 +0000</pubDate>
		<dc:creator>javafuns</dc:creator>
				<category><![CDATA[HTTP / WEB]]></category>
		<category><![CDATA[RDF]]></category>
		<category><![CDATA[SemanticWeb]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.baturu.com/?p=1235</guid>
		<description><![CDATA[The Resource Description Framework (RDF) is a language for representing information about resources in the World Wide Web. It provides a graph structure for making statements about things. RDF is designed to be read and understood by computers. It is not designed to be displayed to people. RDF is the W3C standard for encoding knowledge. It is a specification that fills a particular niche for decentralized, distributed knowledge and provides a framework to enable computer applications to handle data.]]></description>
			<content:encoded><![CDATA[<p>The <strong>Resource Description Framework (RDF)</strong> is a language for representing information about resources in the World Wide Web. It provides a graph structure for making statements about things. RDF is designed to be read and understood by computers. It is not designed to be displayed to people. RDF is the <a href="http://www.w3.org/Consortium/">W3C</a> standard for encoding knowledge. It is a specification that fills a particular niche for <a href="http://ontotext.com/factforge/distribknowledge.html">decentralized, distributed knowledge</a> and provides a framework to enable computer applications to handle data.</p>
<p>RDF was <a href="http://www.w3.org/TR/1999/REC-rdf-syntax-19990222/">originally</a> created in 1999 as a standard on top of <a href="http://en.wikipedia.org/wiki/XML">XML</a> for encoding <a href="http://ontotext.com/factforge/metadata.html">metadata</a>, e.g. data about data. It is a foundation for processing metadata.</p>
<p>RDF specifies the data model and syntax for sharing knowledge about concepts on the Web. It does not specify how concepts may relate to one another.</p>
<p>RDF has a simple data model, based on triples:</p>
<p><em>subject</em> <em>predicate</em> <em>object</em></p>
<p>It is a graph-based formalism for representing metadata, where the subject and the object are things (entities), and the predicate denotes the relationship between them. Each triple represents a fact. The figure below shows <em>Peter</em> to be the subject of the triple, <em>Sofia</em> to be the object, and <em>lives in</em>to be the predicate describing the relationship between <em>Peter</em>, the subject, and <em>Sofia</em>, the object of the triple.</p>
<div id="attachment_1236" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.baturu.com/wp-content/uploads/2010/08/rdf-triple.jpg"><img class="size-medium wp-image-1236" title="RDF triple" src="http://blog.baturu.com/wp-content/uploads/2010/08/rdf-triple-300x45.jpg" alt="RDF triple" width="300" height="45" /></a><p class="wp-caption-text">RDF triple</p></div>
<p>The subject and object are nodes and the predicate (e.g. the property) &#8211; an arc. Properties are represented as a directed arc, so they are only valid from subject to object.<span id="more-1235"></span></p>
<p>RDF statements form a graph by being able to share subjects and objects. Also, the subject of one statement can be the object of another and vice versa. For instance, the figure below shows <em>Sofia</em> to be the object of the triple <em>Peter lives in Sofia</em> and the subject of the triple <em>Sofia located in Bulgaria</em>, and <em>Peter</em> to be the subject of both triples: <em>Peter lives in Sofia</em> and <em>Peter has website www.peter.com</em>.</p>
<div id="attachment_1240" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.baturu.com/wp-content/uploads/2010/08/rdf-subject-object.jpeg"><img class="size-medium wp-image-1240" title="RDF Graph" src="http://blog.baturu.com/wp-content/uploads/2010/08/rdf-subject-object-300x120.jpg" alt="RDF Graph" width="300" height="120" /></a><p class="wp-caption-text">RDF Graph</p></div>
<p>Each subject, predicate and object can have a name, a <a href="http://ontotext.com/factforge/uri.html">URI</a>. In the RDF model, these values are called RDF resources. So, an RDF triple really looks like this:</p>
<table border="1">
<tbody>
<tr>
<td><strong>Subject</strong></td>
<td><strong>Predicate</strong></td>
<td><strong>Object</strong></td>
</tr>
<tr>
<td><code>http://www.anon.com/foaf#Peter</code></td>
<td>http://www.location.org/rdf#lives_in</td>
<td><code>http://www.dbpedia.org/resource/Sofia</code></td>
</tr>
</tbody>
</table>
<p>Each resource is uniquely identified on the Web.</p>
<p>RDF graphs can be represented in <a href="http://www.w3.org/XML/">XML</a>. This is the RDF/XML syntax. XML encoding allows the graphs to be exchanged on the web. The example below shows the representation of the triple <em>Peter lives in Sofia</em> in RDF/XML.</p>
<p><code>&lt;rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"<br />
xmlns:ex="http://www.location.org/"<br />
&lt;rdf:Description rdf:about="http://www.anon.com/foaf#Peter"&gt;<br />
&lt;ex:lives_in&gt;<br />
&lt;ex:location rdf:resource="http://www.dbpedia.org/resource/Sofia" /&gt;<br />
&lt;/ex:lives_in&gt;<br />
&lt;/rdf:Description&gt;<br />
&lt;/rdf:RDF&gt;</code></p>
<p>RDF provides a model for making <a href="http://ontotext.com/factforge/logicalstatement.html">logical statements</a> which could be used for <a href="http://ontotext.com/factforge/definference.html">inference</a> tasks. It is aligned to the Web architecture and is simple enough for uptake and usage. However, it does not specify how concepts may relate to one another.</p>
<p>RDF is part of the <a href="http://www.w3.org/Consortium/">W3C</a>&#8216;s <a href="http://www.w3.org/2001/sw/">Semantic Web Activity</a>. It is a <a href="http://www.w3.org/Consortium/">W3C</a> Recommendation.</p>
<p>The <a href="http://ontotext.com/factforge/rdfs.html"><strong>Resource Description Framework Schema (RDFS)</strong></a> is an extension of RDF. It allows to define simple ontologies &#8211; models about concepts and their properties. They can be used to conclude new knowledge.</p>
<p>The <a href="http://ontotext.com/factforge/owl.html"><strong>Web Ontology Language (OWL)</strong></a> extends RDFS. It makes richer models of knowledge about things possible, but at the cost of those models being more complex for a computer to process.</p>
<p><strong>Original Location:</strong> <a href="http://ontotext.com/factforge/rdf.html" target="_blank">http://ontotext.com/factforge/rdf.html</a></p>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>2010/08/15 -- <a href="http://blog.baturu.com/index.php/2010/08/15/customize_java_packages_generated_by_xmlbeans.html" title="定制 xmlbeans 所生成的 package">定制 xmlbeans 所生成的 package</a></li><li>2010/06/09 -- <a href="http://blog.baturu.com/index.php/2010/06/09/terminologies_in_rdf.html" title="RDF 中的术语">RDF 中的术语</a></li><li>2009/10/21 -- <a href="http://blog.baturu.com/index.php/2009/10/21/tutorial_of_soap_with_attachments_api_for_java.html" title="Tutorial of SOAP with Attachments API for Java">Tutorial of SOAP with Attachments API for Java</a></li><li>2009/07/23 -- <a href="http://blog.baturu.com/index.php/2009/07/23/whats_the_purpose_of_schemalocation_attribute_in_xml.html" title="XML 中的 schemaLocation 属性究竟是什么意思？">XML 中的 schemaLocation 属性究竟是什么意思？</a></li><li>2009/07/19 -- <a href="http://blog.baturu.com/index.php/2009/07/19/smtp_transport_binding_for_soap.html" title="SMTP Transport Binding for SOAP">SMTP Transport Binding for SOAP</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.baturu.com/index.php/2010/08/04/a_brief_introduction_of_whats_rdf.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux批量删除文件</title>
		<link>http://blog.baturu.com/index.php/2010/07/26/delete_files_in_batch_in_linux.html</link>
		<comments>http://blog.baturu.com/index.php/2010/07/26/delete_files_in_batch_in_linux.html#comments</comments>
		<pubDate>Mon, 26 Jul 2010 13:25:16 +0000</pubDate>
		<dc:creator>javafuns</dc:creator>
				<category><![CDATA[Operation Systems]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[OS]]></category>

		<guid isPermaLink="false">http://blog.baturu.com/?p=1230</guid>
		<description><![CDATA[以删除令人厌恶的 .DS_Store 文件为例：
<code>﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿find . -name .DS_Store -exec rm -f {} \;﻿</code>
该 find 命令查找文件名为 .DS_Store 的文件，并将这些文件替换到 {} 部分从而进行删除。
';' 前的参数都作为 rm 的参数， '\' 则是对 ';' 进行 escape。]]></description>
			<content:encoded><![CDATA[<p>以删除令人厌恶的 .DS_Store 文件为例：<br />
<code>﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿﻿find . -name .DS_Store -exec rm -f {} \;﻿</code><br />
该 find 命令查找文件名为 .DS_Store 的文件，并将这些文件替换到 {} 部分从而进行删除。<br />
&#8216;;&#8217; 前的参数都作为 rm 的参数， &#8216;\&#8217; 则是对 &#8216;;&#8217; 进行 escape。</p>
<p>xargs 也挺不错的：<code>find . -name .DS_Store | xargs -i rm -rf {}</code></p>
<p>再看一个例子，查找并打开一个文件：<br />
<code>find . -name HttpServletRequest.java -exec vi {} +</code></p>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>2009/04/26 -- <a href="http://blog.baturu.com/index.php/2009/04/26/how_to_change_the_icon_of_mac_osx_app.html" title="如何更改Mac程序的图标">如何更改Mac程序的图标</a></li><li>2008/08/02 -- <a href="http://blog.baturu.com/index.php/2008/08/02/mac-free-editor.html" title="Mac  上的免费编辑器">Mac  上的免费编辑器</a></li><li>2008/04/29 -- <a href="http://blog.baturu.com/index.php/2008/04/29/how-to-switch-terminals-on-linux.html" title="Linux 图形界面和虚拟终端的相互切换命令">Linux 图形界面和虚拟终端的相互切换命令</a></li><li>2008/04/23 -- <a href="http://blog.baturu.com/index.php/2008/04/23/the-alternative-softwares-of-windows-on-linux.html" title="windows软件的Linux类似/替换/相近品">windows软件的Linux类似/替换/相近品</a></li><li>2008/03/23 -- <a href="http://blog.baturu.com/index.php/2008/03/23/register-code-of-textmate-1-dot-5-dot-5.html" title="好不容易找到的 Textmate 1.5.5 注册码">好不容易找到的 Textmate 1.5.5 注册码</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.baturu.com/index.php/2010/07/26/delete_files_in_batch_in_linux.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>wait and notifyAll in Java multi-threading</title>
		<link>http://blog.baturu.com/index.php/2010/07/16/wait_and_notifyall_in_java_multithreading.html</link>
		<comments>http://blog.baturu.com/index.php/2010/07/16/wait_and_notifyall_in_java_multithreading.html#comments</comments>
		<pubDate>Fri, 16 Jul 2010 03:22:15 +0000</pubDate>
		<dc:creator>javafuns</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Thread]]></category>

		<guid isPermaLink="false">http://blog.baturu.com/?p=1227</guid>
		<description><![CDATA[wait：当线程进入wait()时，会马上释放锁，并进入到wait状态。当该线程被再次唤醒时，继续从等待处往下执行。
notifyAll：当线程执行完notifyAll()，会继续执行剩下的代码，直至退出同步区域，此时才会释放锁。]]></description>
			<content:encoded><![CDATA[<p>wait：当线程进入wait()时，会马上释放锁，并进入到wait状态。当该线程被再次唤醒时，继续从等待处往下执行。</p>
<p>notifyAll：当线程执行完notifyAll()，会继续执行剩下的代码，直至退出同步区域，此时才会释放锁。</p>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>2010/05/07 -- <a href="http://blog.baturu.com/index.php/2010/05/07/executor_in_java_util_concurrent.html" title="java.util.concurrent 中的 Executor">java.util.concurrent 中的 Executor</a></li><li>2010/05/06 -- <a href="http://blog.baturu.com/index.php/2010/05/06/callable_and_future_in_java_util_concurrent.html" title="java.util.concurrent 中的 Callable 和 Future">java.util.concurrent 中的 Callable 和 Future</a></li><li>2010/04/29 -- <a href="http://blog.baturu.com/index.php/2010/04/29/new_synchronization_mechanism_in_java_threads.html" title="New Synchronization Mechanism in Java Threads">New Synchronization Mechanism in Java Threads</a></li><li>2009/07/22 -- <a href="http://blog.baturu.com/index.php/2009/07/22/some_java_thread_tips.html" title="Java Thread 注意事项">Java Thread 注意事项</a></li><li>2010/08/15 -- <a href="http://blog.baturu.com/index.php/2010/08/15/customize_java_packages_generated_by_xmlbeans.html" title="定制 xmlbeans 所生成的 package">定制 xmlbeans 所生成的 package</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.baturu.com/index.php/2010/07/16/wait_and_notifyall_in_java_multithreading.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>关于 java.util.concurrent 您不知道的 5 件事(转载)</title>
		<link>http://blog.baturu.com/index.php/2010/07/13/5_things_you_didnt_know_about_java_util_concurrent.html</link>
		<comments>http://blog.baturu.com/index.php/2010/07/13/5_things_you_didnt_know_about_java_util_concurrent.html#comments</comments>
		<pubDate>Tue, 13 Jul 2010 03:09:48 +0000</pubDate>
		<dc:creator>javafuns</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog.baturu.com/?p=1224</guid>
		<description><![CDATA[简介：编写能够良好执行，防止应用程序受损的多线程代码是很艰巨的任务 — 这也是为什么我们需要 java.util.concurrent 的原因。Ted Neward 会向您说明并发 Collections 类，比如 CopyOnWriteArrayList，BlockingQueue，还有 ConcurrentMap，如何针对您的并发编程需求改进标准 Collections 类。
除了具有很好的并发性的 Collections，java.util.concurrent 还引入了其他一些预先构建的组件，它们可帮助您调整和执行多线程应用程序中的线程。Ted Neward 介绍在 Java™ 编程过程中使用 java.util.concurrent 包要注意的 5 点。]]></description>
			<content:encoded><![CDATA[<p><strong><em>通过并发 Collections 进行多线程编程</em></strong></p>
<p><em><a rel="#authortip1" href="http://www.ibm.com/developerworks/cn/java/j-5things4.html#author1">Ted Neward</a>, 总裁，ThoughtWorks, ThoughtWorks</em></p>
<p><em><strong>简介：</strong> 编写能够良好执行，防止应用程序受损的多线程代码是很艰巨的任务 — 这也是为什么我们需要 <code>java.util.concurrent</code> 的原因。Ted Neward 会向您说明并发 Collections 类，比如<code>CopyOnWriteArrayList</code>，<code>BlockingQueue</code>，还有 <code>ConcurrentMap</code>，如何针对您的并发编程需求改进标准 Collections 类。<br />
除了具有很好的并发性的 Collections，<code>java.util.concurrent</code> 还引入了其他一些预先构建的组件，它们可帮助您调整和执行多线程应用程序中的线程。Ted Neward 介绍在 Java™ 编程过程中使用 <code>java.util.concurrent</code> 包要注意的 5 点。</em></p>
<h2>第一部分</h2>
<p>Concurrent Collections 是 Java™ 5 的巨大附加产品，但是在关于注释和泛型的争执中很多 Java  开发人员忽视了它们。此外（或者更老实地说），许多开发人员避免使用这个数据包，因为他们认为它一定很复杂，就像它所要解决的问题一样。</p>
<p>事实上，<code>java.util.concurrent</code> 包含许多类，能够有效解决普通的并发问题，无需复杂工序。阅读本文，了解 <code>java.util.concurrent</code> 类，比如 <code>CopyOnWriteArrayList</code> 和 <code>BlockingQueue</code> 如何帮助您解决多线程编程的棘手问题。</p>
<h3><em><a name="N100AA">1. TimeUnit</a></em></h3>
<p>尽管<em>本质上</em> 不是 Collections 类，但 <code>java.util.concurrent.TimeUnit</code> 枚举让代码更易读懂。使用 <code>TimeUnit</code> 将使用您的方法或 API 的开发人员从毫秒的 “暴政” 中解放出来。<br />
<span id="more-1224"></span><br />
<code>TimeUnit</code> 包括所有时间单位，从 <code>MILLISECONDS</code> 和 <code>MICROSECONDS</code> 到 <code>DAYS</code> 和 <code>HOURS</code>，这就意味着它能够处理一个开发人员所需的几乎所有的时间范围类 型。同时，因为在列举上声明了转换方法，在时间加快时，将 <code>HOURS</code> 转换回 <code>MILLISECONDS</code> 甚至变得更容易。</p>
<div>
<hr /></div>
<h3><em><a name="N100DD">2. CopyOnWriteArrayList</a></em></h3>
<p>创建数组的全新副本是过于昂贵的操作，无论是从时间上，还是从内存开销上，因此在通常使用中很少考虑；开发人员往往求助于使用同步的 <code>ArrayList</code>。 然而，这也是一个成本较高的选择，因为每当您跨集合内容进行迭代时，您就不得不同步所有操作，包括读和写，以此保证一致性。</p>
<p>这又让成本结构回到这样一个场景：需多读者都在读取 <code>ArrayList</code>，但是几乎没人会去修改它。</p>
<p><code>CopyOnWriteArrayList</code> 是个巧妙的小宝贝，能解决这一问题。它的 Javadoc 将 <code>CopyOnWriteArrayList</code> 定义为一个 “<code>ArrayList</code> 的线程安全变体，在这个变体中所有易变操作（添加，设置等）可以通过复制全新的数组来实现”。</p>
<p>集合从内部将它的内容复制到一个没有修改的新数组，这样读者访问数组内容时就不会产生同步成本（因为他们从来不是在易变数据上操作）。</p>
<p>本质上讲，<code>CopyOnWriteArrayList</code> 很适合处理 <code>ArrayList</code> 经常让我们失败的这种场景：读取频繁，但很少有写操作的集合，例如 JavaBean 事件的 <code>Listener</code>s。</p>
<div>
<hr /></div>
<h3><em><a name="N10112">3. BlockingQueue</a></em></h3>
<p><code>BlockingQueue</code> 接口表示它是一个 <code>Queue</code>，意思是它的项以先入先出 （FIFO）顺序存储。在特定顺序插入的项以相同的顺序检索 —  但是需要附加保证，从空队列检索一个项的任何尝试都会阻塞调用线程，直到这个项准备好被检索。同理，想要将一个项插入到满队列的尝试也会导致阻塞调用线 程，直到队列的存储空间可用。</p>
<p><code>BlockingQueue</code> 干净利落地解决了如何将一个线程收集的项“传递”给另一线程用于处理的问题，无需考虑同步问题。Java Tutorial 的 Guarded  Blocks 试用版就是一个很好的例子。它构建一个单插槽绑定的缓存，当新的项可用，而且插槽也准备好接受新的项时，使用手动同步和 <code>wait()</code>/<code>notifyAll()</code> 在线程之间发信。（详见 <a href="http://java.sun.com/docs/books/tutorial/essential/concurrency/guardmeth.html">Guarded  Blocks 实现</a>。）</p>
<p>尽管 Guarded Blocks 教程中的代码有效，但是它耗时久，混乱，而且也并非完全直观。退回到 Java  平台较早的时候，没错，Java 开发人员不得不纠缠于这种代码；但现在是 2010 年 — 情况难道没有改善？</p>
<p>清单 1 显示了 Guarded Blocks 代码的重写版，其中我使用了一个 <code>ArrayBlockingQueue</code>， 而不是手写的 <code>Drop</code>。<br />
<a name="listing1"><strong>清单 1. BlockingQueue</strong></a></p>
<pre name="code" class="java">import java.util.*;
import java.util.concurrent.*;

class Producer implements Runnable
{
    private BlockingQueue&lt;String&gt; drop;
    List&lt;String&gt; messages = Arrays.asList(
        "Mares eat oats",
        "Does eat oats",
        "Little lambs eat ivy",
        "Wouldn't you eat ivy too?");

    public Producer(BlockingQueue&lt;String&gt; d) { this.drop = d; }

    public void run()
    {
        try
        {
            for (String s : messages)
                drop.put(s);
            drop.put("DONE");
        }
        catch (InterruptedException intEx)
        {
            System.out.println("Interrupted! " +
                "Last one out, turn out the lights!");
        }
    }
}

class Consumer implements Runnable
{
    private BlockingQueue&lt;String&gt; drop;
    public Consumer(BlockingQueue&lt;String&gt; d) { this.drop = d; }

    public void run()
    {
        try
        {
            String msg = null;
            while (!((msg = drop.take()).equals("DONE")))
                System.out.println(msg);
        }
        catch (InterruptedException intEx)
        {
            System.out.println("Interrupted! " + "Last one out, turn out the lights!");
        }
    }
}

public class ABQApp
{
    public static void main(String[] args)
    {
        BlockingQueue&lt;String&gt; drop = new ArrayBlockingQueue(1, true);
        (new Thread(new Producer(drop))).start();
        (new Thread(new Consumer(drop))).start();
    }
}</pre>
<p><code>ArrayBlockingQueue</code> 还体现了“公平” —  意思是它为读取器和编写器提供线程先入先出访问。这种替代方法是一个更有效，但又冒穷尽部分线程风险的政策。（即，允许一些读取器在其他读取器锁定时运行 效率更高，但是您可能会有读取器线程的流持续不断的风险，导致编写器无法进行工作。）</p>
<div>
<h4><em>注意  Bug！</em></h4>
<div>
<em>顺便说一句，如果您注意到 Guarded Blocks 包含一个重大 bug，那么您是对的 — 如果开发人员在 <code>main()</code> 中的 <code>Drop</code> 实例上同步，会出现什么情况呢？</em>
</div>
</div>
<p><code>BlockingQueue</code> 还支持接收时间参数的方法，时间参数表明线程在返回信号故障以插入或者检索有关项之前需要阻塞的时间。这么做会避免非绑定的等待，这对一个生产系统是致命 的，因为一个非绑定的等待会很容易导致需要重启的系统挂起。</p>
<div>
<hr /></div>
<h3><em><a name="N10178">4. ConcurrentMap</a></em></h3>
<p><code>Map</code> 有一个微妙的并发 bug，这个 bug 将许多不知情的 Java 开发人员引入歧途。<code>ConcurrentMap</code> 是最容易的解决方案。</p>
<p>当一个 <code>Map</code> 被从多个线程访问时，通常使用 <code>containsKey()</code> 或者 <code>get()</code> 来查看给定键是否在存储键/值对之前出现。但是即使有一个同步的 <code>Map</code>，线程还是可以在这个过程中潜入，然后夺取对 <code>Map</code> 的控制权。问题是，在对 <code>put()</code> 的调用中，锁在 <code>get()</code> 开始时获取，然后在可以再次获取锁之前释放。它的结果是个竞争条件：这是两个线程之间的竞争，结果也会因谁先运行而不同。</p>
<p>如果两个线程几乎同时调用一个方法，两者都会进行测试，调用 put，在处理中丢失第一线程的值。幸运的是，<code>ConcurrentMap</code> 接口支持许多附加方法，它们设计用于在一个锁下进行两个任务：<code>putIfAbsent()</code>，例如，首先进行测试，然后仅当键 没有存储在 <code>Map</code> 中时进行 put。</p>
<div>
<hr /></div>
<h3><em><a name="N101B7">5. SynchronousQueues</a></em></h3>
<p>根据 Javadoc，<code>SynchronousQueue</code> 是个有趣的东西：</p>
<blockquote><p>这是一个阻塞队列，其中，每个插入操作必须等待另一个线程的对应移除操作，反之亦然。一个同步队列不具有任何内部容量，甚至不具有 1 的容量。</p></blockquote>
<p>本质上讲，<code>SynchronousQueue</code> 是之前提过的 <code>BlockingQueue</code> 的又一实现。它给我们提供了在线程之间交换单一元素的极轻量级方法，使用 <code>ArrayBlockingQueue</code> 使用的阻塞语义。在清单 2 中，我重写了 <a href="http://www.ibm.com/developerworks/cn/java/j-5things4.html#listing1">清 单 1</a> 的代码，使用 <code>SynchronousQueue</code> 替代 <code>ArrayBlockingQueue</code>：<br />
<a name="listing2"><strong>清单 2. SynchronousQueue</strong></a></p>
<pre name="code" class="java">import java.util.*;
import java.util.concurrent.*;

class Producer implements Runnable
{
    private BlockingQueue&lt;String&gt; drop;
    List&lt;String&gt; messages = Arrays.asList(
        "Mares eat oats",
        "Does eat oats",
        "Little lambs eat ivy",
        "Wouldn't you eat ivy too?");

    public Producer(BlockingQueue&lt;String&gt; d) { this.drop = d; }

    public void run()
    {
        try
        {
            for (String s : messages)
                drop.put(s);
            drop.put("DONE");
        }
        catch (InterruptedException intEx)
        {
            System.out.println("Interrupted! " +
                "Last one out, turn out the lights!");
        }
    }
}

class Consumer
    implements Runnable
{
    private BlockingQueue&lt;String&gt; drop;
    public Consumer(BlockingQueue&lt;String&gt; d) { this.drop = d; }

    public void run()
    {
        try
        {
            String msg = null;
            while (!((msg = drop.take()).equals("DONE")))
                System.out.println(msg);
        }
        catch (InterruptedException intEx)
        {
            System.out.println("Interrupted! " +
                "Last one out, turn out the lights!");
        }
    }
}

public class SynQApp
{
    public static void main(String[] args)
    {
        BlockingQueue&lt;String&gt; drop = new SynchronousQueue&lt;String&gt;();
        (new Thread(new Producer(drop))).start();
        (new Thread(new Consumer(drop))).start();
    }
}</pre>
<p>实现代码看起来几乎相同，但是应用程序有额外获益：<code>SynchronousQueue</code> 允许在队列进行一个插入，只要有一个线程等着使用它。</p>
<p>在实践中，<code>SynchronousQueue</code> 类似于 Ada 和 CSP 等语言中可用的  “会合通道”。这些通道有时在其他环境中也称为 “连接”，这样的环境包括 .NET （见 <a href="http://www.ibm.com/developerworks/cn/java/j-5things4.html#resources">参考资料</a>）。</p>
<p>并发 Collections  提供了线程安全、经过良好调优的数据结构，简化了并发编程。然而，在一些情形下，开发人员需要更进一步，思考如何调节和/或限制线程执行。由于 <code>java.util.concurrent</code> 的总体目标是简化多线程编程，您可能希望该包包含同步实用程序，而它确实包含。</p>
<h2>第二部分</h2>
<p>本文是 <a href="https://www.ibm.com/developerworks/cn/java/j-5things4.html">第 1 部分</a> 的延续，将介绍几个比核心语言原语（监视器）更高级的同步结构，但它们还未包含在 Collection  类中。一旦您了解了这些锁和门的用途，使用它们将非常直观。</p>
<h3><em><a name="N10093">1. Semaphore</a></em></h3>
<p>在一些企业系统中，开发人员经常需要限制未处理的特定资源请求（线程/操作）数量，事实上，限制有时候能够提高系统的吞吐量，因为它们减少了 对特定资源的争用。尽管完全可以手动编写限制代码，但使用 Semaphore 类可以更轻松地完成此任务，它将帮您执行限制，如清单 1 所示：<br />
<a name="listing1"><strong>清单 1. 使用 Semaphore 执行限制</strong></a></p>
<pre name="code" class="java">
import java.util.*;import java.util.concurrent.*;

public class SemApp
{
    public static void main(String[] args)
    {
        Runnable limitedCall = new Runnable() {
            final Random rand = new Random();
            final Semaphore available = new Semaphore(3);
            int count = 0;
            public void run()
            {
                int time = rand.nextInt(15);
                int num = count++;

                try
                {
                    available.acquire();
                    System.out.println("Executing " + "long-running action for " + time + " seconds... #" + num);
                    Thread.sleep(time * 1000);
                    System.out.println("Done with #" + num + "!");
                    available.release();
                }
                catch (InterruptedException intEx)
                {
                    intEx.printStackTrace();
                }
            }
        };

        for (int i=0; i&lt;10; i++)
            new Thread(limitedCall).start();
    }
}
</pre>
<p>即使本例中的 10 个线程都在运行（您可以对运行 <code>SemApp</code> 的 Java 进程执行 <code>jstack</code> 来验证），但只有 3 个线程是活跃的。在一个信号计数器释放之前，其他 7 个线程都处于空闲状态。（实际上，<code>Semaphore</code> 类支持一次获取和释放多个 <em>permit</em>，但这不适用于本场景。）</p>
<div>
<hr /></div>
<h3><em><a name="N100B8">2. CountDownLatch</a></em></h3>
<p>如果 <code>Semaphore</code> 是允许一次进入一个（这可能会勾起一些流行夜总会的保安的记忆）线程的并发性类，那么  <code>CountDownLatch</code> 就像是赛马场的起跑门栅。此类持有所有空闲线程，直到满足特定条件，这时它将会一次释放所有这些线程。<br />
<a name="listing2"><strong>清单 2. CountDownLatch：让我们去赛马吧！</strong></a></p>
<pre name="code" class="java">
import java.util.*;
import java.util.concurrent.*;

class Race
{
    private Random rand = new Random();

    private int distance = rand.nextInt(250);
    private CountDownLatch start;
    private CountDownLatch finish;

    private List&lt;String&gt; horses = new ArrayList&lt;String&gt;();

    public Race(String... names)
    {
        this.horses.addAll(Arrays.asList(names));
    }

    public void run()
        throws InterruptedException
    {
        System.out.println("And the horses are stepping up to the gate...");
        final CountDownLatch start = new CountDownLatch(1);
        final CountDownLatch finish = new CountDownLatch(horses.size());
        final List&lt;String&gt; places =  Collections.synchronizedList(new ArrayList&lt;String&gt;());

        for (final String h : horses)
        {
            new Thread(new Runnable() {
                public void run() {
                    try
                    {
                        System.out.println(h +  " stepping up to the gate...");
                        start.await();

                        int traveled = 0;
                        while (traveled &lt; distance)
                        {
                            // In a 0-2 second period of time....
                            Thread.sleep(rand.nextInt(3) * 1000);

                            // ... a horse travels 0-14 lengths
                            traveled += rand.nextInt(15);
                            System.out.println(h +  " advanced to " + traveled + "!");
                        }
                        finish.countDown();
                        System.out.println(h + " crossed the finish!");
                        places.add(h);
                    }
                    catch (InterruptedException intEx)
                    {
                        System.out.println("ABORTING RACE!!!");
                        intEx.printStackTrace();
                    }
                }
            }).start();
        }

        System.out.println("And... they're off!");
        start.countDown();        

        finish.await();
        System.out.println("And we have our winners!");
        System.out.println(places.get(0) + " took the gold...");
        System.out.println(places.get(1) + " got the silver...");
        System.out.println("and " + places.get(2) + " took home the bronze.");
    }
}

public class CDLApp
{
    public static void main(String[] args) throws InterruptedException, java.io.IOException
    {
        System.out.println("Prepping...");

        Race r = new Race(
            "Beverly Takes a Bath",
            "RockerHorse",
            "Phineas",
            "Ferb",
            "Tin Cup",
            "I'm Faster Than a Monkey",
            "Glue Factory Reject"
            );

        System.out.println("It's a race of " + r.getDistance() + " lengths");

        System.out.println("Press Enter to run the race....");
        System.in.read();

        r.run();
    }
}
</pre>
<p>注意，在 <a href="http://www.ibm.com/developerworks/cn/java/j-5things5.html#listing2">清 单 2</a> 中，<code>CountDownLatch</code> 有两个用途：首先，它同时释放所有线程，模拟马赛的起点，但随后会设置一个门闩模拟马赛的终点。这样，“主” 线程就可以输出结果。  为了让马赛有更多的输出注释，可以在赛场的 “转弯处” 和 “半程” 点，比如赛马跨过跑道的四分之一、二分之一和四分之三线时，添加 <code>CountDownLatch</code>。</p>
<div>
<hr /></div>
<h3><em><a name="N100E2">3. Executor</a></em></h3>
<p><a href="http://www.ibm.com/developerworks/cn/java/j-5things5.html#listing1">清 单 1</a> 和 <a href="http://www.ibm.com/developerworks/cn/java/j-5things5.html#listing2">清 单 2</a> 中的示例都存在一个重要的缺陷，它们要求您直接创建 <code>Thread</code> 对象。这可以解决一些问题，因为在一些  JVM 中，创建 <code>Thread</code> 是一项重量型的操作，重用现有 <code>Thread</code> 比创建新线程要容易得多。而在另一些 JVM 中，情况正好相反：<code>Thread</code> 是轻量型的，可以在需要时很容易地新建一个线程。当然，如果 Murphy  拥有自己的解决办法（他通常都会拥有），那么您无论使用哪种方法对于您最终将部署的平台都是不对的。</p>
<p>JSR-166 专家组（参见 <a href="http://www.ibm.com/developerworks/cn/java/j-5things5.html#resources">参 考资料</a>）在一定程度上预测到了这一情形。Java 开发人员无需直接创建 <code>Thread</code>，他们引入了 <code>Executor</code> 接口，这是对创建新线程的一种抽象。如清单 3 所示，<code>Executor</code> 使您不必亲自对 <code>Thread</code> 对象执行 <code>new</code> 就能够创建新线程：<br />
<a name="listing3"><strong>清单 3. Executor</strong></a></p>
<pre name="code" class="java">
Executor exec = getAnExecutorFromSomeplace();
exec.execute(new Runnable() { ... });
</pre>
<p>使用 <code>Executor</code> 的主要缺陷与我们在所有工厂中遇到的一样：工厂必须来自某个位置。不幸的是，与 CLR  不同，JVM 没有附带一个标准的 VM 级线程池。</p>
<p><code>Executor</code> 类<em>实际上</em> 充当着一个提供 <code>Executor</code> 实现实例的共同位置，但它只有 <code>new</code> 方法（例如用于创建新线程池）；它没有预先创建实例。所以您可以自行决定是否希望在代码中创建和使用 <code>Executor</code> 实例。（或者在某些情况下，您将能够使用所选的容器/平台提供的实例。）</p>
<p><a name="N10145">ExecutorService 随时可以使用</a></p>
<p>尽管不必担心 <code>Thread</code> 来自何处，但 <code>Executor</code> 接口缺乏 Java  开发人员可能期望的某种功能，比如结束一个用于生成结果的线程并以非阻塞方式等待结果可用。（这是桌面应用程序的一个常见需求，用户将执行需要访问数据库 的 UI 操作，然后如果该操作花费了很长时间，可能希望在它完成之前取消它。）</p>
<p>对于此问题，JSR-166 专家创建了一个更加有用的抽象（<code>ExecutorService</code> 接口），它将线程启动工厂建模为一个可集中控制的服务。例如，无需每执行一项任务就调用一次 <code>execute()</code>，<code>ExecutorService</code> 可以接受一组任务并返回一个表示每项任务的未来结果的<em>未来列表</em>。</p>
<div>
<hr /></div>
<h3><em><a name="N10168">4. ScheduledExecutorServices</a></em></h3>
<p>尽管 <code>ExecutorService</code> 接口非常有用，但某些任务仍需要以计划方式执行，比如以确定的时间间隔或在特定时间执行给定的任务。这就是 <code>ScheduledExecutorService</code> 的应用范围，它扩展了 <code>ExecutorService</code>。</p>
<p>如果您的目标是创建一个每隔 5 秒跳一次的 “心跳” 命令，使用 <code>ScheduledExecutorService</code> 可以轻松实现，如清单 4 所示：<br />
<a name="listing4"><strong>清单 4. ScheduledExecutorService 模拟心跳</strong></a></p>
<pre name="code" class="java">
import java.util.concurrent.*;

public class Ping
{
    public static void main(String[] args)
    {
        ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
        Runnable pinger = new Runnable() {
            public void run() {
                System.out.println("PING!");
            }
        };
        ses.scheduleAtFixedRate(pinger, 5, 5, TimeUnit.SECONDS);
    }
}</pre>
<p>这项功能怎么样？不用过于担心线程，不用过于担心用户希望取消心跳时会发生什么，也不用明确地将线程标记为前台或后台；只需将所有的计划细节 留给 <code>ScheduledExecutorService</code>。</p>
<p>顺便说一下，如果用户希望取消心跳，<code>scheduleAtFixedRate</code> 调用将返回一个 <code>ScheduledFuture</code> 实例，它不仅封装了结果（如果有），还拥有一个 <code>cancel</code> 方法来关闭计划的操作。</p>
<div>
<hr /></div>
<h3><em><a name="N101A4">5. Timeout 方法</a></em></h3>
<p>为阻塞操作设置一个具体的超时值（以避免死锁）的能力是 <code>java.util.concurrent</code> 库相比起早期并发特性的一大进步，比如监控锁定。</p>
<p>这些方法几乎总是包含一个 <code>int</code>/<code>TimeUnit</code> 对，指示这些方法应该等待多长时间才释放控制权并将其返回给程序。它需要开发人员执行更多工作 — 如果没有获取锁，您将如何重新获取？ —  但结果几乎总是正确的：更少的死锁和更加适合生产的代码。（关于编写生产就绪代码的更多信息，请参见 <a href="http://www.ibm.com/developerworks/cn/java/j-5things5.html#resources">参 考资料</a> 中 Michael Nygard 编写的 <em>Release It!</em>。）</p>
<div>
<hr /></div>
<h3><em><a name="N101C7">结束语</a></em></h3>
<p><code>java.util.concurrent</code> 包还包含了其他许多好用的实用程序，它们很好地扩展到了  Collections 之外，尤其是在 <code>.locks</code> 和 <code>.atomic</code> 包中。深入研究，您还将发现一些有用的控制结构，比如 <code>CyclicBarrier</code> 等。</p>
<p>与 Java 平台的许多其他方面一样，您无需费劲地查找可能非常有用的基础架构代码。在编写多线程代码时，请记住本文讨论的实用程序和 <a href="http://www.ibm.com/developerworks/cn/java/j-5things4.html">上一篇文章</a> 中讨论的实用程序。</p>
<h3><em><a name="author">关于作者</a></em></h3>
<p><em>Ted Neward 是 Neward &amp; Associates 的主管，负责有关 Java、.NET、XML  服务和其他平台的咨询、指导、培训和推介。他现在居住在华盛顿州西雅图附近。</em></p>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>2010/08/15 -- <a href="http://blog.baturu.com/index.php/2010/08/15/customize_java_packages_generated_by_xmlbeans.html" title="定制 xmlbeans 所生成的 package">定制 xmlbeans 所生成的 package</a></li><li>2010/07/16 -- <a href="http://blog.baturu.com/index.php/2010/07/16/wait_and_notifyall_in_java_multithreading.html" title="wait and notifyAll in Java multi-threading">wait and notifyAll in Java multi-threading</a></li><li>2010/05/07 -- <a href="http://blog.baturu.com/index.php/2010/05/07/executor_in_java_util_concurrent.html" title="java.util.concurrent 中的 Executor">java.util.concurrent 中的 Executor</a></li><li>2010/05/06 -- <a href="http://blog.baturu.com/index.php/2010/05/06/callable_and_future_in_java_util_concurrent.html" title="java.util.concurrent 中的 Callable 和 Future">java.util.concurrent 中的 Callable 和 Future</a></li><li>2010/04/29 -- <a href="http://blog.baturu.com/index.php/2010/04/29/new_synchronization_mechanism_in_java_threads.html" title="New Synchronization Mechanism in Java Threads">New Synchronization Mechanism in Java Threads</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.baturu.com/index.php/2010/07/13/5_things_you_didnt_know_about_java_util_concurrent.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RDF 中的术语</title>
		<link>http://blog.baturu.com/index.php/2010/06/09/terminologies_in_rdf.html</link>
		<comments>http://blog.baturu.com/index.php/2010/06/09/terminologies_in_rdf.html#comments</comments>
		<pubDate>Wed, 09 Jun 2010 08:39:52 +0000</pubDate>
		<dc:creator>javafuns</dc:creator>
				<category><![CDATA[HTTP / WEB]]></category>
		<category><![CDATA[RDF]]></category>

		<guid isPermaLink="false">http://blog.baturu.com/?p=1212</guid>
		<description><![CDATA[RDF Dataset : represents a collection of graphs. An RDF Dataset comprises one graph, the default graph, which does not have a name, and zero or more named graphs, where each named graph is identified by an IRI.﻿ Related Posts:2010/08/04 -- A brief introduction of what is RDF]]></description>
			<content:encoded><![CDATA[<p><strong><em>RDF Dataset</em></strong> : represents a  collection of graphs. An RDF Dataset comprises one graph, the default  graph, which  does not have a name, and zero or more named graphs, where each named  graph is identified by  an IRI.﻿</p>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>2010/08/04 -- <a href="http://blog.baturu.com/index.php/2010/08/04/a_brief_introduction_of_whats_rdf.html" title="A brief introduction of what is RDF">A brief introduction of what is RDF</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.baturu.com/index.php/2010/06/09/terminologies_in_rdf.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>java.util.concurrent 中的 Executor</title>
		<link>http://blog.baturu.com/index.php/2010/05/07/executor_in_java_util_concurrent.html</link>
		<comments>http://blog.baturu.com/index.php/2010/05/07/executor_in_java_util_concurrent.html#comments</comments>
		<pubDate>Fri, 07 May 2010 09:53:18 +0000</pubDate>
		<dc:creator>javafuns</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Thread]]></category>

		<guid isPermaLink="false">http://blog.baturu.com/?p=1208</guid>
		<description><![CDATA[java.util.concurrent 中包含有线程池的实现, 以及 Runnable 和 Callable 的执行器(Executor), 通过使用线程池, 可减少创建线程的开销.
以下介绍按照编写线程的通常顺序进行.]]></description>
			<content:encoded><![CDATA[<p>java.util.concurrent 中包含有线程池的实现, 以及 Runnable 和 Callable 的执行器(Executor), 通过使用线程池, 可减少创建线程的开销.</p>
<p>以下介绍按照编写线程的通常顺序进行.</p>
<h3>一. Executors 类: 线程执行器的工厂类</h3>
<p>这个类提供了很多工厂方法, 可用来获取 Executor、ExecutorService、ScheduledExecutorService、ThreadFactory 和 Callable 类, 所以通常情况下, 应该通过本类来取得这些接口的实例.  对于 Executor、ExecutorService、ScheduledExecutorService、ThreadFactory 和  Callable 等接口或类, 将在下面介绍.</p>
<p>比如:</p>
<ul>
<li><span> <code>static <a title="java.util.concurrent 中的接口" href="file:///home/javafuns/.chmsee/bookshelf/df03c9cf37c5fbc5a7894e04297127d7/java/util/concurrent/ExecutorService.html">ExecutorService</a></code></span> <code><strong><a href="file:///home/javafuns/.chmsee/bookshelf/df03c9cf37c5fbc5a7894e04297127d7/java/util/concurrent/Executors.html#newCachedThreadPool%28%29">newCachedThreadPool</a></strong>()</code></li>
</ul>
<p style="padding-left: 30px;">创建一个可根据需要创建新线程的线程池，但是在以前构造的线程可用时将重用它们。</p>
<ul>
<li><span> <code>static <a title="java.util.concurrent 中的接口" href="file:///home/javafuns/.chmsee/bookshelf/df03c9cf37c5fbc5a7894e04297127d7/java/util/concurrent/ExecutorService.html">ExecutorService</a></code></span> <code><strong><a href="file:///home/javafuns/.chmsee/bookshelf/df03c9cf37c5fbc5a7894e04297127d7/java/util/concurrent/Executors.html#newFixedThreadPool%28int%29">newFixedThreadPool</a></strong>(int nThreads)</code></li>
</ul>
<p style="padding-left: 30px;">创建一个可重用固定线程数的线程池，以共享的无界队列方式来运行这些线程。</p>
<ul>
<li><span> <code>static <a title="java.util.concurrent 中的接口" href="file:///home/javafuns/.chmsee/bookshelf/df03c9cf37c5fbc5a7894e04297127d7/java/util/concurrent/ScheduledExecutorService.html">ScheduledExecutorService</a></code></span> <code><strong><a href="file:///home/javafuns/.chmsee/bookshelf/df03c9cf37c5fbc5a7894e04297127d7/java/util/concurrent/Executors.html#newScheduledThreadPool%28int%29">newScheduledThreadPool</a></strong>(int corePoolSize)</code></li>
</ul>
<p style="padding-left: 30px;">创建一个线程池，它可安排在给定延迟后运行命令或者定期地执行。</p>
<p>也分别可以创建单线程执行程序, 如:</p>
<ul>
<li><span> <code>static <a title="java.util.concurrent 中的接口" href="file:///home/javafuns/.chmsee/bookshelf/df03c9cf37c5fbc5a7894e04297127d7/java/util/concurrent/ExecutorService.html">ExecutorService</a></code></span> <code><strong><a href="file:///home/javafuns/.chmsee/bookshelf/df03c9cf37c5fbc5a7894e04297127d7/java/util/concurrent/Executors.html#newSingleThreadExecutor%28%29">newSingleThreadExecutor</a></strong>()</code></li>
</ul>
<p style="padding-left: 30px;">创建一个使用单个 worker 线程的 Executor，以无界队列方式来运行该线程。</p>
<ul>
<li><span> <code>static <a title="java.util.concurrent 中的接口" href="file:///home/javafuns/.chmsee/bookshelf/df03c9cf37c5fbc5a7894e04297127d7/java/util/concurrent/ScheduledExecutorService.html">ScheduledExecutorService</a></code></span> <code><strong><a href="file:///home/javafuns/.chmsee/bookshelf/df03c9cf37c5fbc5a7894e04297127d7/java/util/concurrent/Executors.html#newSingleThreadScheduledExecutor%28%29">newSingleThreadScheduledExecutor</a></strong>()</code></li>
</ul>
<p style="padding-left: 30px;">创建一个单线程执行程序，它可安排在给定延迟后运行命令或者定期地执行。</p>
<h3>二. Executor 接口: 线程执行器</h3>
<p>执行已提交的 <a title="java.lang 中的接口" href="file:///home/javafuns/.chmsee/bookshelf/df03c9cf37c5fbc5a7894e04297127d7/java/lang/Runnable.html"><code>Runnable</code></a> 任务的对象。此接口提供一种将任务提交与每个任务将如何运行的机制（包括线程使用的细节、调度等）分离开来的方法。</p>
<ul>
<li><span> <code>void</code></span> <code><strong><a href="file:///home/javafuns/.chmsee/bookshelf/df03c9cf37c5fbc5a7894e04297127d7/java/util/concurrent/Executor.html#execute%28java.lang.Runnable%29">execute</a></strong>(<a title="java.lang 中的接口" href="file:///home/javafuns/.chmsee/bookshelf/df03c9cf37c5fbc5a7894e04297127d7/java/lang/Runnable.html">Runnable</a> command)</code></li>
</ul>
<p style="padding-left: 30px;">在未来某个时间执行给定的命令。</p>
<p>通常使用 <tt>Executor</tt> 而不是显式地创建线程。例如，可能会使用以下方法，而不是为一组任务中的每个任务调用 <tt>new  Thread(new(RunnableTask())).start()</tt>：</p>
<pre name="code" class="java"> Executor executor = anExecutor;
 executor.execute(new RunnableTask1());
 executor.execute(new RunnableTask2());
 ...
</pre>
<p>不过，<tt>Executor</tt> 接口并没有严格地要求执行是异步的。在最简单的情况下，执行程序可以在调用者的线程中立即运行已提交的任务：</p>
<pre name="code" class="java"> class DirectExecutor implements Executor {
     public void execute(Runnable r) {
         r.run();
     }
 }</pre>
<p>更常见的是，任务是在某个不是调用者线程的线程中执行的。以下执行程序将为每个任务生成一个新线程。</p>
<pre name="code" class="java"> class ThreadPerTaskExecutor implements Executor {
     public void execute(Runnable r) {
         new Thread(r).start();
     }
 }</pre>
<h3>三. ExecutorService、ScheduledExecutorService 接口: 线程池</h3>
<p>(一) 中提到的 ExecutorService、ScheduledExecutorService 都是 Executor 的子接口, ExecutorService、ScheduledExecutorService 也提供了自己所特有的方法声明:</p>
<ul>
<li>终止当前任务:
<ul>
<li>void     shutdown()<br />
启动一次顺序关闭，执行以前提交的任务，但不接受新任务。</li>
<li>List&lt;Runnable&gt;     shutdownNow()<br />
试图停止所有正在执行的活动任务，暂停处理正在等待的任务，并返回等待执行的任务列表。</li>
</ul>
</li>
<li>单个任务提交:  扩展了 Executor 的 execute(Runnable) 方法
<ul>
<li>&lt;T&gt; Future&lt;T&gt;    submit(Callable&lt;T&gt; task)<br />
提交一个返回值的任务用于执行，返回一个表示任务的未决结果的 Future。</li>
<li>Future&lt;?&gt;     submit(Runnable task)<br />
提交一个 Runnable 任务用于执行，并返回一个表示该任务的 Future。</li>
<li>&lt;T&gt; Future&lt;T&gt;  submit(Runnable task, T result)<br />
提交一个 Runnable 任务用于执行，并返回一个表示该任务的 Future。</li>
</ul>
</li>
<li> 批量任务提交:
<ul>
<li>&lt;T&gt; List&lt;Future&lt;T&gt;&gt;    invokeAll(Collection&lt;? extends Callable&lt;T&gt;&gt; tasks)<br />
执行给定的任务，当所有任务完成时，返回保持任务状态和结果的 Future 列表。</li>
<li>&lt;T&gt; List&lt;Future&lt;T&gt;&gt; invokeAll(Collection&lt;? extends Callable&lt;T&gt;&gt; tasks, long timeout, TimeUnit unit)<br />
执行给定的任务，当所有任务完成或超时期满时（无论哪个首先发生），返回保持任务状态和结果的 Future 列表。</li>
<li>&lt;T&gt; T     invokeAny(Collection&lt;? extends Callable&lt;T&gt;&gt; tasks)<br />
执行给定的任务，如果某个任务已成功完成（也就是未抛出异常），则返回其结果。</li>
<li>&lt;T&gt; T   invokeAny(Collection&lt;? extends Callable&lt;T&gt;&gt; tasks, long timeout, TimeUnit unit)<br />
执行给定的任务，如果在给定的超时期满前某个任务已成功完成（也就是未抛出异常），则返回其结果。</li>
</ul>
</li>
</ul>
<h3>四. ThreadPoolExecutor、ScheduledThreadPoolExecutor 类: 线程池具体实现</h3>
<p>这是线程池(ExecutorService、ScheduledExecutorService)的具体实现. 如非必要, 请使用 Executors 创建一个线程池.  此类提供了一些 Hook 方法, 所以大部分该类的子类都扩展了这些 hook 方法.</p>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>2010/07/16 -- <a href="http://blog.baturu.com/index.php/2010/07/16/wait_and_notifyall_in_java_multithreading.html" title="wait and notifyAll in Java multi-threading">wait and notifyAll in Java multi-threading</a></li><li>2010/05/06 -- <a href="http://blog.baturu.com/index.php/2010/05/06/callable_and_future_in_java_util_concurrent.html" title="java.util.concurrent 中的 Callable 和 Future">java.util.concurrent 中的 Callable 和 Future</a></li><li>2010/04/29 -- <a href="http://blog.baturu.com/index.php/2010/04/29/new_synchronization_mechanism_in_java_threads.html" title="New Synchronization Mechanism in Java Threads">New Synchronization Mechanism in Java Threads</a></li><li>2009/07/22 -- <a href="http://blog.baturu.com/index.php/2009/07/22/some_java_thread_tips.html" title="Java Thread 注意事项">Java Thread 注意事项</a></li><li>2010/08/15 -- <a href="http://blog.baturu.com/index.php/2010/08/15/customize_java_packages_generated_by_xmlbeans.html" title="定制 xmlbeans 所生成的 package">定制 xmlbeans 所生成的 package</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://blog.baturu.com/index.php/2010/05/07/executor_in_java_util_concurrent.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
