﻿<?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>C++博客-mysileng-随笔分类-Java</title><link>http://www.cppblog.com/mysileng/category/20000.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 09 Apr 2014 08:26:53 GMT</lastBuildDate><pubDate>Wed, 09 Apr 2014 08:26:53 GMT</pubDate><ttl>60</ttl><item><title>在java中使用Runtime.exec()时要注意的问题</title><link>http://www.cppblog.com/mysileng/archive/2014/04/08/206500.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Tue, 08 Apr 2014 07:20:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2014/04/08/206500.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/206500.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2014/04/08/206500.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/206500.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/206500.html</trackback:ping><description><![CDATA[<p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">程序如下：</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">import java.util.*;</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">import java.io.*;</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">public class BadExecJavac</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">{</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; public static void main(String args[])</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; {</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Runtime rt = Runtime.getRuntime();</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Process proc = rt.exec("javac");</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int exitVal = proc.exitValue();</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Process exitValue: " + exitVal);</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Throwable t)</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; t.printStackTrace();</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; }</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">}</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">运行结果如下</p><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">E:\classes\com\javaworld\jpitfalls\article2&gt;java BadExecJavac<br />java.lang.IllegalThreadStateException: process has not exited&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />at java.lang.Win32Process.exitValue(Native Method)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />at BadExecJavac.main(BadExecJavac.java:13)</span><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">这是因为当进程还没有结束的情况下，调用exitValue方法会抛出IllegalThreadStateException.当然了我们会问为什吗这个方法不会等到进程结束在返回一个合理的值？</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">在检查Process类的所有可用方法以后我们发现WairFor()是一个更合适的方法。事实上waitFor也会返回exit value。这意味着你不可以同时用exitvalue和waitfor，而是只能选择一个。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">当然了也有情况你要在waitfor之前用exitvalue方法：就是你不想因为外部程序永远无法完成而一直等待下去。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">因此为了避免这个陷阱，我们要么捕获IllegalThreadStateException异常，要么等待进程完成。我们相当然的以为可以用waitfor来等待程序的结束。代码如下：</p><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">import java.util.*;<br />import java.io.*;<br />public class BadExecJavac2{&nbsp;&nbsp;&nbsp;<br /></span>&nbsp; &nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">public static void main(String args[])&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">try&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">Runtime rt = Runtime.getRuntime();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">Process proc = rt.exec("javac");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">&nbsp;int exitVal = proc.waitFor();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">System.out.println("Process exitValue: " + exitVal);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">} catch (Throwable t)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">t.printStackTrace();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">}&nbsp;&nbsp;&nbsp; <br /></span>&nbsp; &nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">}<br />}</span><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">这次在linux下面返回的结果是2,而在windows下面据说程序会挂起，关于其原因我们可以在jdk文档中找到部分解释：因为一些操作系统为标准的输入输出仅仅提供有限的缓冲区，当不能正确的将信息写进输入流或者从输出流中获取信息时，就会导致子进程的阻塞，甚至死锁。现在我们就根据jdk文档来处理javac进程的输出，当你不带任何参数运行javac时，它会打印出一系列的有用的提示信息。而这些会被传送到stderr流中。我们可以写程序在其返回前获取这些信息。下面的代码提供了一个平庸的解决方案。</p><span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">import java.util.*;import java.io.*;<br />public class MediocreExecJavac{&nbsp;&nbsp;&nbsp; <br /></span>&nbsp; &nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">public static void main(String args[])&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;"> try&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">Runtime rt = Runtime.getRuntime();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">Process proc = rt.exec("javac");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">&nbsp;InputStream stderr = proc.getErrorStream();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /></span>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">&nbsp;InputStreamReader isr = new InputStreamReader(stderr);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">BufferedReader br = new BufferedReader(isr);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">String line = null;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">System.out.println("&lt;ERROR&gt;");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">while ( (line = br.readLine()) != null)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">System.out.println(line);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">System.out.println("&lt;/ERROR&gt;");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">int exitVal = proc.waitFor();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">System.out.println("Process exitValue: " + exitVal);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">} catch (Throwable t)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;"> t.printStackTrace();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">}&nbsp;&nbsp;&nbsp; <br /></span>&nbsp; &nbsp;<span style="color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">}<br />}</span><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">这次程序可以正确的输出了提示信息，但是我们应该注意到其返回代码是2，我们知道任何非0的返回代码都表示程序不正常。所以我们需要进一步的查找原因。对于win32而言是file not found，很明显javac期望我们提供编译的文件。所以对于永远挂起的问题，如果你运行的程序会有输出或者要求输出入时，你需要处理输出和输入。我在linux下面运行的结果是正确的。前面说了在win32下面2代表是文件没有找到，而在这种情况下表明是dir.exe没有找到，（因为根本就没有这个文件，他们都被封装到common.com （win95）或者cmd.exe中了。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">下面我们列出一个正确的处理Process的输入输出流的方法。需要用一个线程类。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">import java.util.*;<br />import java.io.*;<br />class StreamGobbler extends Thread{&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;InputStream is;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;String type;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;StreamGobbler(InputStream is, String type)&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.is = is;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.type = type;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;public void run()&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputStreamReader isr = new InputStreamReader(is);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BufferedReader br = new BufferedReader(isr);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String line=null;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; while ( (line = br.readLine()) != null)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; System.out.println(type + "&gt;" + line);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp; &nbsp; &nbsp;&nbsp;} catch (IOException ioe)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;ioe.printStackTrace(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp; &nbsp; &nbsp;&nbsp;}&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;}<br />}</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">用于专门的处理输入输出。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">public class GoodWindowsExec{&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>public static void main(String args[])&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>if (args.length &lt; 1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>System.out.println("USAGE: java GoodWindowsExec &lt;cmd&gt;");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>System.exit(1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>try&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>String osName = System.getProperty("os.name" );&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>String[] cmd = new String[3];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>if( osName.equals( "Windows NT" ) )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>cmd[0] = "cmd.exe" ;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>cmd[1] = "/C" ;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>cmd[2] = args[0];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else if( osName.equals( "Windows 95" ) )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>cmd[0] = "command.com" ;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>cmd[1] = "/C" ;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>cmd[2] = args[0];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>Runtime rt = Runtime.getRuntime();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>System.out.println("Execing " + cmd[0] + " " + cmd[1] + " " + cmd[2]);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>Process proc = rt.exec(cmd);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // any error message?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR"); &nbsp;// any output?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// kick them off&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>errorGobbler.start();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>outputGobbler.start();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// any error???&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>int exitVal = proc.waitFor();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>System.out.println("ExitValue: " + exitVal);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>} catch (Throwable t)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>t.printStackTrace(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>&nbsp; &nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>}&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;<span class="Apple-tab-span" style="white-space:pre">	</span>}<br />}</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">如果运行如下命令上面的代码会调用word程序</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">&gt;java GoodWindowExec &#8220;abc.doc&#8221;</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">也就是说文件类型如果window能够识别它就会调用对应的程序处理。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;">StreamGlobbler的最重要作用是他会清空所有的传递给他的inputstream，这样不会造成Process阻塞或者死锁。</p><p style="margin: 0px; padding: 0px; color: #454545; font-family: tahoma, helvetica, arial; background-color: #ffffff;"></p><img src ="http://www.cppblog.com/mysileng/aggbug/206500.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2014-04-08 15:20 <a href="http://www.cppblog.com/mysileng/archive/2014/04/08/206500.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java中wait/notify机制</title><link>http://www.cppblog.com/mysileng/archive/2014/04/07/206494.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Mon, 07 Apr 2014 09:27:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2014/04/07/206494.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/206494.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2014/04/07/206494.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/206494.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/206494.html</trackback:ping><description><![CDATA[<p><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">通常，多线程之间需要协调工作。例如，浏览器的一个显示图片的线程displayThread想要执行显示图片的任务，必须等待下载线程 downloadThread将该图片下载完毕。如果图片还没有下载完，displayThread可以暂停，当downloadThread完成了任务 后，再通知displayThread&#8220;图片准备完毕，可以显示了&#8221;，这时，displayThread继续执行。</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">以上逻辑简单的说就是：如果条件不满足，则等待。当条件满足时，等待该条件的线程将被唤醒。在Java中，这个机制的实现依赖于wait/notify。等待机制与锁机制是密切关联的。例如：</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">synchronized(obj) {while(!condition) {obj.wait();}obj.doSomething();}&nbsp;&nbsp;</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">当线程A获得了obj锁后，发现条件condition不满足，无法继续下一处理，于是线程A就wait()。</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">在另一线程B中，如果B更改了某些条件，使得线程A的condition条件满足了，就可以唤醒线程A：</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">synchronized(obj) {condition = true;obj.notify();}<span class="Apple-converted-space">&nbsp;</span></span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">需要注意的概念是：</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">&#9670;调用obj的wait(), notify()方法前，必须获得obj锁，也就是必须写在synchronized(obj) {...} 代码段内。</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">&#9670;调用obj.wait()后，线程A就释放了obj的锁，否则线程B无法获得obj锁，也就无法在synchronized(obj) {...} 代码段内唤醒A。</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">&#9670;当obj.wait()方法返回后，线程A需要再次获得obj锁，才能继续执行。</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">&#9670;如果A1,A2,A3都在obj.wait()，则B调用obj.notify()只能唤醒A1,A2,A3中的一个（具体哪一个由JVM决定）。</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">&#9670;obj.notifyAll()则能全部唤醒A1,A2,A3，但是要继续执行obj.wait()的下一条语句，必须获得obj锁，因此，A1,A2,A3只有一个有机会获得锁继续执行，例如A1，其余的需要等待A1释放obj锁之后才能继续执行。</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">&#9670;当B调用obj.notify/notifyAll的时候，B正持有obj锁，因此，A1,A2,A3虽被唤醒，但是仍无法获得obj锁。直到B退出synchronized块，释放obj锁后，A1,A2,A3中的一个才有机会获得锁继续执行。</span></p><img src ="http://www.cppblog.com/mysileng/aggbug/206494.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2014-04-07 17:27 <a href="http://www.cppblog.com/mysileng/archive/2014/04/07/206494.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CentOS 下JDK安装(转)</title><link>http://www.cppblog.com/mysileng/archive/2012/12/25/196619.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Tue, 25 Dec 2012 11:17:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2012/12/25/196619.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/196619.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2012/12/25/196619.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/196619.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/196619.html</trackback:ping><description><![CDATA[<p style="padding: 0px 0px 15px; margin: 0px; color: #2c2c2c; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff; ">第一步：查看Linux自带的JDK是否已安装 （卸载centOS已安装的1.4）</p><p style="padding: 0px 0px 15px; margin: 0px; color: #2c2c2c; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff; ">安装好的CentOS会自带OpenJdk,用命令 java -version ，会有下面的信息：</p><p style="padding: 0px 0px 15px; margin: 0px; color: #2c2c2c; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff; ">java version "1.6.0"<br style="padding: 0px; margin: 0px; " />OpenJDK Runtime Environment (build 1.6.0-b09)<br style="padding: 0px; margin: 0px; " />OpenJDK 64-Bit Server VM (build 1.6.0-b09, mixed mode)</p><p style="padding: 0px 0px 15px; margin: 0px; color: #2c2c2c; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff; ">最好还是先卸载掉openjdk,在安装sun公司的jdk.</p><p style="padding: 0px 0px 15px; margin: 0px; color: #2c2c2c; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff; ">先查看 rpm -qa | grep java</p><p style="padding: 0px 0px 15px; margin: 0px; color: #2c2c2c; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff; ">显示如下信息：</p><p style="padding: 0px 0px 15px; margin: 0px; color: #2c2c2c; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff; ">java-1.4.2-gcj-compat-1.4.2.0-40jpp.115<br style="padding: 0px; margin: 0px; " />java-1.6.0-openjdk-1.6.0.0-1.7.b09.el5</p><p style="padding: 0px 0px 15px; margin: 0px; color: #2c2c2c; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff; ">卸载：</p><p style="padding: 0px 0px 15px; margin: 0px; color: #2c2c2c; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff; ">rpm -e --nodeps java-1.4.2-gcj-compat-1.4.2.0-40jpp.115<br style="padding: 0px; margin: 0px; " />rpm -e --nodeps java-1.6.0-openjdk-1.6.0.0-1.7.b09.el5</p><p style="padding: 0px 0px 15px; margin: 0px; color: #2c2c2c; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff; ">还有一些其他的命令</p><p style="padding: 0px 0px 15px; margin: 0px; color: #2c2c2c; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff; ">rpm -qa | grep gcj</p><p style="padding: 0px 0px 15px; margin: 0px; color: #2c2c2c; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff; ">rpm -qa | grep jdk</p><p style="padding: 0px 0px 15px; margin: 0px; color: #2c2c2c; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff; ">如果出现找不到openjdk source的话，那么还可以这样卸载</p><p style="padding: 0px 0px 15px; margin: 0px; color: #2c2c2c; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff; ">yum -y remove java java-1.4.2-gcj-compat-1.4.2.0-40jpp.115<br style="padding: 0px; margin: 0px; " />yum -y remove java java-1.6.0-openjdk-1.6.0.0-1.7.b09.el5</p><p style="padding: 0px 0px 15px; margin: 0px; color: #2c2c2c; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff; ">&nbsp;</p><p style="padding: 0px 0px 15px; margin: 0px; color: #2c2c2c; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff; ">&nbsp;</p><p style="padding: 0px 0px 15px; margin: 0px; color: #2c2c2c; font-family: 宋体, 'Arial Narrow', arial, serif; line-height: 28px; background-color: #ffffff; ">&lt;1&gt;# rpm -qa|grep jdk &#8592; 查看jdk的信息或直接执行&nbsp;<br style="padding: 0px; margin: 0px; " />或&nbsp;<br style="padding: 0px; margin: 0px; " /># rpm -q jdk&nbsp;<br style="padding: 0px; margin: 0px; " />或&nbsp;<br style="padding: 0px; margin: 0px; " /># java -version&nbsp;<br style="padding: 0px; margin: 0px; " />&lt;2&gt;# rpm -qa | grep gcj &#8592; 确认gcj的版本号&nbsp;<br style="padding: 0px; margin: 0px; " />&lt;3&gt;# yum -y remove java-1.4.2-gcj-compat &#8592; 卸载gcj&nbsp;<br style="padding: 0px; margin: 0px; " /><br style="padding: 0px; margin: 0px; " />第二步：安装JDK&nbsp;<br style="padding: 0px; margin: 0px; " />&lt;1&gt;从SUN下载jdk-1_5_0_14-linux-i586-rpm.bin或jdk-1_5_0_14-linux-i586.bin&nbsp;<br style="padding: 0px; margin: 0px; " />在/usr下新建java文件夹，将安装包放在/usr/java目录下&nbsp;<br style="padding: 0px; margin: 0px; " /># mkdir /usr/java&nbsp;<br style="padding: 0px; margin: 0px; " />&lt;2&gt;安装JDK&nbsp;<br style="padding: 0px; margin: 0px; " /># cd /usr/java&nbsp;<br style="padding: 0px; margin: 0px; " />&#9312;jdk-1_5_0_14-linux-i586-rpm.bin文件安装&nbsp;<br style="padding: 0px; margin: 0px; " /># chmod 777 jdk-1_5_0_14-linux-i586-rpm.bin &#8592; 修改为可执行&nbsp;<br style="padding: 0px; margin: 0px; " /># ./jdk-1_5_0_14-linux-i586-rpm.bin &#8592; 选择yes同意上面的协议&nbsp;<br style="padding: 0px; margin: 0px; " /># rpm -ivh jdk-1_5_0_14-linux-i586.rpm &#8592; 选择yes直到安装完毕&nbsp;<br style="padding: 0px; margin: 0px; " />&#9313;jdk-1_5_0_14-linux-i586.bin文件安装&nbsp;<br style="padding: 0px; margin: 0px; " /># chmod a+x jdk-1_5_0_14-linux-i586.bin &#8592; 使当前用户拥有执行权限&nbsp;<br style="padding: 0px; margin: 0px; " /># ./jdk-1_5_0_14-linux-i586.bin &#8592; 选择yes直到安装完毕&nbsp;<br style="padding: 0px; margin: 0px; " /><br style="padding: 0px; margin: 0px; " />第三步：配置环境变量&nbsp;<br style="padding: 0px; margin: 0px; " />&lt;1&gt;# vi /etc/profile&nbsp;<br style="padding: 0px; margin: 0px; " />&lt;2&gt;在最后加入以下几行：&nbsp;<br style="padding: 0px; margin: 0px; " />export JAVA_HOME=/usr/java/jdk1.6.0_10&nbsp;<br style="padding: 0px; margin: 0px; " />export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar&nbsp;<br style="padding: 0px; margin: 0px; " />export PATH=$PATH:$JAVA_HOME/bin&nbsp;<br style="padding: 0px; margin: 0px; " />&lt;3&gt;# reboot &#8592; 重启机器配置生效</p><img src ="http://www.cppblog.com/mysileng/aggbug/196619.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2012-12-25 19:17 <a href="http://www.cppblog.com/mysileng/archive/2012/12/25/196619.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java RMI demo(转)</title><link>http://www.cppblog.com/mysileng/archive/2012/09/26/192076.html</link><dc:creator>鑫龙</dc:creator><author>鑫龙</author><pubDate>Wed, 26 Sep 2012 06:07:00 GMT</pubDate><guid>http://www.cppblog.com/mysileng/archive/2012/09/26/192076.html</guid><wfw:comment>http://www.cppblog.com/mysileng/comments/192076.html</wfw:comment><comments>http://www.cppblog.com/mysileng/archive/2012/09/26/192076.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mysileng/comments/commentRss/192076.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mysileng/services/trackbacks/192076.html</trackback:ping><description><![CDATA[<div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">Java RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制，能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">&nbsp;</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">Java RMI不是什么新技术（在Java1.1的时代都有了），但却是是非常重要的底层技术。</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">大名鼎鼎的EJB都是建立在rmi基础之上的，现在还有一些开源的远程调用组件，其底层技术也是rmi。</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">&nbsp;</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">在大力鼓吹Web Service、SOA的时代，是不是每个应用都应该选用笨拙的Web Service组件来实现，通过对比测试后，RMI是最简单的，在一些小的应用中是最合适的。</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">&nbsp;</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">下面通过一个简单的例子来说明RMI的原理和应用，下面这个例子是一个简单HelloWorld，但已涵盖RMI的核心应用与开发模式。</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">&nbsp;</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; "><div style="margin: 0px; padding: 4px; border: 1px solid #cccccc; font-size: 10pt; width: 886.7166748046875px; color: #000000; word-break: break-all; line-height: 16px; font-family: verdana, 宋体; background-color: #eeeeee; ">/**&nbsp;<br style="margin: 0px; padding: 0px; " />* Created by IntelliJ IDEA.&nbsp;<br style="margin: 0px; padding: 0px; " />* User: leizhimin&nbsp;<br style="margin: 0px; padding: 0px; " />* Date: 2008-8-7 21:50:02&nbsp;<br style="margin: 0px; padding: 0px; " />* 定义一个远程接口，必须继承Remote接口，其中需要远程调用的方法必须抛出RemoteException异常&nbsp;<br style="margin: 0px; padding: 0px; " />*/&nbsp;<br style="margin: 0px; padding: 0px; " />public&nbsp;interface&nbsp;IHello&nbsp;extends&nbsp;Remote {&nbsp;<br style="margin: 0px; padding: 0px; " /><br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;/**&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; * 简单的返回&#8220;Hello World！"字样&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; * @return 返回&#8220;Hello World！"字样&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; * @throws java.rmi.RemoteException&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; */&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;String helloWorld()&nbsp;throws&nbsp;RemoteException;&nbsp;<br style="margin: 0px; padding: 0px; " /><br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;/**&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; * 一个简单的业务方法，根据传入的人名返回相应的问候语&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; * @param someBodyName&nbsp;&nbsp;人名&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; * @return 返回相应的问候语&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; * @throws java.rmi.RemoteException&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; */&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;String sayHelloToSomeBody(String someBodyName)&nbsp;throws&nbsp;RemoteException;&nbsp;<br style="margin: 0px; padding: 0px; " />}</div></div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">&nbsp;</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; "><div style="margin: 0px; padding: 4px; border: 1px solid #cccccc; font-size: 10pt; width: 886.7166748046875px; color: #000000; word-break: break-all; line-height: 16px; font-family: verdana, 宋体; background-color: #eeeeee; ">/**&nbsp;<br style="margin: 0px; padding: 0px; " />* Created by IntelliJ IDEA.&nbsp;<br style="margin: 0px; padding: 0px; " />* User: leizhimin&nbsp;<br style="margin: 0px; padding: 0px; " />* Date: 2008-8-7 21:56:47&nbsp;<br style="margin: 0px; padding: 0px; " />* 远程的接口的实现&nbsp;<br style="margin: 0px; padding: 0px; " />*/&nbsp;<br style="margin: 0px; padding: 0px; " />public&nbsp;class&nbsp;HelloImpl&nbsp;extends&nbsp;UnicastRemoteObject&nbsp;implements&nbsp;IHello {&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;/**&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; * 因为UnicastRemoteObject的构造方法抛出了RemoteException异常，因此这里默认的构造方法必须写，必须声明抛出RemoteException异常&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; * @throws RemoteException&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; */&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;HelloImpl()&nbsp;throws&nbsp;RemoteException {&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br style="margin: 0px; padding: 0px; " /><br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;/**&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; * 简单的返回&#8220;Hello World！"字样&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; * @return 返回&#8220;Hello World！"字样&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; * @throws java.rmi.RemoteException&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; */&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;String helloWorld()&nbsp;throws&nbsp;RemoteException {&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;"Hello World!";&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br style="margin: 0px; padding: 0px; " /><br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;/**&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; * 一个简单的业务方法，根据传入的人名返回相应的问候语&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; * @param someBodyName 人名&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; * @return 返回相应的问候语&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; * @throws java.rmi.RemoteException&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp; */&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;String sayHelloToSomeBody(String someBodyName)&nbsp;throws&nbsp;RemoteException {&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;"你好，"&nbsp;+ someBodyName +&nbsp;"!";&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br style="margin: 0px; padding: 0px; " />}</div></div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">&nbsp;</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; "><div style="margin: 0px; padding: 4px; border: 1px solid #cccccc; font-size: 10pt; width: 886.7166748046875px; color: #000000; word-break: break-all; line-height: 16px; font-family: verdana, 宋体; background-color: #eeeeee; ">/**&nbsp;<br style="margin: 0px; padding: 0px; " />* Created by IntelliJ IDEA.&nbsp;<br style="margin: 0px; padding: 0px; " />* User: leizhimin&nbsp;<br style="margin: 0px; padding: 0px; " />* Date: 2008-8-7 22:03:35&nbsp;<br style="margin: 0px; padding: 0px; " />* 创建RMI注册表，启动RMI服务，并将远程对象注册到RMI注册表中。&nbsp;<br style="margin: 0px; padding: 0px; " />*/&nbsp;<br style="margin: 0px; padding: 0px; " />public&nbsp;class&nbsp;HelloServer {&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String args[]) {&nbsp;<br style="margin: 0px; padding: 0px; " /><br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//创建一个远程对象&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IHello rhello =&nbsp;new&nbsp;HelloImpl();&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//本地主机上的远程对象注册表Registry的实例，并指定端口为8888，这一步必不可少（Java默认端口是1099），必不可缺的一步，缺少注册表创建，则无法绑定对象到远程注册表上&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LocateRegistry.createRegistry(8888);&nbsp;<br style="margin: 0px; padding: 0px; " /><br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//把远程对象注册到RMI注册服务器上，并命名为RHello&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//绑定的URL标准格式为：rmi://host:port/name(其中协议名可以省略，下面两种写法都是正确的）&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Naming.bind("rmi://localhost:8888/RHello",rhello);&nbsp;<br style="margin: 0px; padding: 0px; " />//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Naming.bind("//localhost:8888/RHello",rhello);&nbsp;<br style="margin: 0px; padding: 0px; " /><br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("&gt;&gt;&gt;&gt;&gt;INFO:远程IHello对象绑定成功！");&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(RemoteException e) {&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("创建远程对象发生异常！");&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(AlreadyBoundException e) {&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("发生重复绑定对象异常！");&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(MalformedURLException e) {&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("发生URL畸形异常！");&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br style="margin: 0px; padding: 0px; " />}</div></div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">&nbsp;</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; "><div style="margin: 0px; padding: 4px; border: 1px solid #cccccc; font-size: 10pt; width: 886.7166748046875px; color: #000000; word-break: break-all; line-height: 16px; font-family: verdana, 宋体; background-color: #eeeeee; ">/**&nbsp;<br style="margin: 0px; padding: 0px; " />* Created by IntelliJ IDEA.&nbsp;<br style="margin: 0px; padding: 0px; " />* User: leizhimin&nbsp;<br style="margin: 0px; padding: 0px; " />* Date: 2008-8-7 22:21:07&nbsp;<br style="margin: 0px; padding: 0px; " />* 客户端测试，在客户端调用远程对象上的远程方法，并返回结果。&nbsp;<br style="margin: 0px; padding: 0px; " />*/&nbsp;<br style="margin: 0px; padding: 0px; " />public&nbsp;class&nbsp;HelloClient {&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;void&nbsp;main(String args[]){&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//在RMI服务注册表中查找名称为RHello的对象，并调用其上的方法&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IHello rhello =(IHello) Naming.lookup("rmi://localhost:8888/RHello");&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(rhello.helloWorld());&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(rhello.sayHelloToSomeBody("熔岩"));&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(NotBoundException e) {&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(MalformedURLException e) {&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(RemoteException e) {&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();&nbsp;&nbsp;&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br style="margin: 0px; padding: 0px; " />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br style="margin: 0px; padding: 0px; " />}</div></div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">&nbsp;</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">运行RMI服务端程序：</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; "><img alt="" src="http://img1.51cto.com/attachment/200808/200808071218121453750.png" border="0" style="margin: 0px; padding: 0px; border: 0px; " /></div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">&nbsp;</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">运行RMI客户端程序：</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; "><img alt="" src="http://img1.51cto.com/attachment/200808/200808071218121504000.png" border="0" style="margin: 0px; padding: 0px; border: 0px; " /></div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">&nbsp;</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">总结：</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">从上面的过程来看，RMI对服务器的IP地址和端口依赖很紧密，但是在开发的时候不知道将来的服务器IP和端口如何，但是客户端程序依赖这个IP和端口。</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">这也是RMI的局限性之一。这个问题有两种解决途径：一是通过DNS来解决，二是通过封装将IP暴露到程序代码之外。</div><div style="margin: 0px; color: #393939; font-family: verdana, 'ms song', Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19px; background-color: #faf7ef; ">RMI的局限性之二是RMI是Java语言的远程调用，两端的程序语言必须是Java实现，对于不同语言间的通讯可以考虑用Web Service或者公用对象请求代理体系（CORBA）来实现。</div><img src ="http://www.cppblog.com/mysileng/aggbug/192076.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mysileng/" target="_blank">鑫龙</a> 2012-09-26 14:07 <a href="http://www.cppblog.com/mysileng/archive/2012/09/26/192076.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>