﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-junjie</title><link>http://www.blogjava.net/junjie/</link><description /><language>zh-cn</language><lastBuildDate>Mon, 18 May 2026 23:51:43 GMT</lastBuildDate><pubDate>Mon, 18 May 2026 23:51:43 GMT</pubDate><ttl>60</ttl><item><title>心情调整</title><link>http://www.blogjava.net/junjie/archive/2009/05/11/270112.html</link><dc:creator>wangjunjie</dc:creator><author>wangjunjie</author><pubDate>Mon, 11 May 2009 13:23:00 GMT</pubDate><guid>http://www.blogjava.net/junjie/archive/2009/05/11/270112.html</guid><description><![CDATA[今天是5月11日，今天我去整形了。把我的疤痕有整小了一部份，这下不是很高兴啊！为什么这么说呢？我一直很高兴哎！！！嘿嘿！现在这么感觉有点怕听见心中那些自卑妥协的声音。害怕在回到从前。呵呵 时光永远都不可能倒流！如果能倒流那么多伟人都能神了！时间永远不可能倒流的！这是自然规律！<br />
我知道怎么回事了！想起以前的事情啦!以前怎么啦！以前想起这块疤上火 自卑啦！呵呵 过去的都已经过去啦！我也不要怪自己！为什么呢?我为什么要怪自己呢？如果这块疤长到谁身上谁有能一点不难过呢？有几个人能做的比我好呢？有几个人能经历了这么大的痛苦还挺过来啦呢！呵呵 这就是毅力啊！<br />
你在好好想想 菲菲还感觉这块疤痕很好看来！其实话有说回来了，我有什么好难过的！就算我现在这块疤痕没整理的话！有块红色也挺好的！<br />
就咱这模样!脸型他们真挡不住！在侧面他们还感觉是撞的呢！都说有点颜色脸上挺好看的呢！虽然咱有疤但咱这模样就眼夹旁边的这块疤跟咱这模样张的一点也不别小白脸那种模样差！你没比没数！这么多人 能张的小白脸的那个层次的人已经不多了！人已经很多了！我到了这个层次已经很高了！其实你一直感到难看的事，到最后真有小姑娘真有人很欣赏这些！我又何苦遭这个罪呢！呵呵 模样真的已经很不错了！每个人都渴望漂亮，如果能变的很漂亮 谁又何尝不<br />
愿意呢?因为这个东西都是父母给决定的不是自己说了算的！ 这是太正常的事情，你看看那么多张的那么一般的人不还都照样过的挺美的！因为我真的很不错啊！生活的好好坏坏不是有模样决定！真正幸福的生活是靠自己的努力！你看看身边的那些男人们！不用你张的多么帅！只要你有颗乐观坚强 宽容善良的心就够了！你的生活决定是很美好的！有心爱的女孩 有成功的事业！怒路吧！孩子你已经完成了 该完的一项任务！放弃这个吧！放弃了！全心的开始！也是全新的开始！因为明天真是太美好了！
<img src ="http://www.blogjava.net/junjie/aggbug/270112.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junjie/" target="_blank">wangjunjie</a> 2009-05-11 21:23 <a href="http://www.blogjava.net/junjie/archive/2009/05/11/270112.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>超连接</title><link>http://www.blogjava.net/junjie/archive/2009/03/31/263226.html</link><dc:creator>wangjunjie</dc:creator><author>wangjunjie</author><pubDate>Tue, 31 Mar 2009 12:17:00 GMT</pubDate><guid>http://www.blogjava.net/junjie/archive/2009/03/31/263226.html</guid><wfw:comment>http://www.blogjava.net/junjie/comments/263226.html</wfw:comment><comments>http://www.blogjava.net/junjie/archive/2009/03/31/263226.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junjie/comments/commentRss/263226.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junjie/services/trackbacks/263226.html</trackback:ping><description><![CDATA[http://www.3y11.com/
<img src ="http://www.blogjava.net/junjie/aggbug/263226.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junjie/" target="_blank">wangjunjie</a> 2009-03-31 20:17 <a href="http://www.blogjava.net/junjie/archive/2009/03/31/263226.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>子窗口</title><link>http://www.blogjava.net/junjie/archive/2009/03/25/261955.html</link><dc:creator>wangjunjie</dc:creator><author>wangjunjie</author><pubDate>Wed, 25 Mar 2009 14:35:00 GMT</pubDate><guid>http://www.blogjava.net/junjie/archive/2009/03/25/261955.html</guid><description><![CDATA[【1、最基本的弹出窗口代码】 <br />
<br />
&lt;SCRIPT LANGUAGE="javascript"&gt; <br />
&lt;!-- <br />
window.open ('page.html') <br />
--&gt; <br />
&lt;/SCRIPT&gt; <br />
<br />
因为这是一段javascripts代码，所以它们应该放在&lt;SCRIPT LANGUAGE="javascript"&gt;标签和&lt;/script&gt;之间。&lt;!-- 和 --&gt;是对一些版本低的浏览器起作用，在这些老浏览器中不会将标签中的代码作为文本显示出来。要养成这个好习惯啊。window.open ('page.html') 用于控制弹出新的窗口page.html，如果page.html不与主窗口在同一路径下，前面应写明路径，绝对路径(<a href="http:///" target="_blank">http://</a>)和相对路径(../)均可。用单引号和双引号都可以，只是不要混用。这一段代码可以加入HTML的任意位置，&lt;head&gt;和&lt;/head&gt;之间可以，&lt;body&gt;间&lt;/body&gt;也可以，越前越早执行，尤其是页面代码长，又想使页面早点弹出就尽量往前放。 <br />
<br />
【2、经过设置后的弹出窗口】 <br />
<br />
下面再说一说弹出窗口的设置。只要再往上面的代码中加一点东西就可以了。我们来定制这个弹出的窗口的外观，尺寸大小，弹出的位置以适应该页面的具体情况。 <br />
<br />
&lt;SCRIPT LANGUAGE="javascript"&gt; <br />
&lt;!-- <br />
window.open ('page.html', 'newwindow', 'height=100, width=400, top=0, left=0, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=n o, status=no') //这句要写成一行 <br />
--&gt; <br />
&lt;/SCRIPT&gt; <br />
<br />
参数解释： <br />
<br />
&lt;SCRIPT LANGUAGE="javascript"&gt; js脚本开始； <br />
window.open 弹出新窗口的命令； <br />
'page.html' 弹出窗口的文件名； <br />
'newwindow' 弹出窗口的名字（不是文件名），非必须，可用空''代替； <br />
height=100 窗口高度； <br />
width=400 窗口宽度； <br />
top=0 窗口距离屏幕上方的象素值； <br />
left=0 窗口距离屏幕左侧的象素值； <br />
toolbar=no 是否显示工具栏，yes为显示； <br />
menubar，scrollbars 表示菜单栏和滚动栏。 <br />
resizable=no 是否允许改变窗口大小，yes为允许； <br />
location=no 是否显示地址栏，yes为允许； <br />
status=no 是否显示状态栏内的信息（通常是文件已经打开），yes为允许； <br />
&lt;/SCRIPT&gt; js脚本结束 <br />
<br />
【3、用函数控制弹出窗口】 <br />
<br />
下面是一个完整的代码。 <br />
&lt;html&gt; <br />
&lt;head&gt; <br />
&lt;script LANGUAGE="JavaScript"&gt; <br />
&lt;!-- <br />
function openwin() { <br />
window.open ("page.html", "newwindow", "height=100, width=400, toolbar =no, menubar=no, scrollbars=no, resizable=no, location=no, status=no") //写成一行 <br />
} <br />
//--&gt; <br />
&lt;/script&gt; <br />
&lt;/head&gt; <br />
&lt;body onload="openwin()"&gt; <br />
任意的页面内容... <br />
&lt;/body&gt; <br />
&lt;/html&gt; <br />
<br />
这里定义了一个函数openwin(),函数内容就是打开一个窗口。在调用它之前没有任何用途。怎么调用呢？ <br />
<br />
方法一：&lt;body onload="openwin()"&gt; 浏览器读页面时弹出窗口； <br />
方法二：&lt;body onunload="openwin()"&gt; 浏览器离开页面时弹出窗口； <br />
方法三：用一个连接调用： <br />
&lt;a href="#" onclick="openwin()"&gt;打开一个窗口&lt;/a&gt; <br />
注意：使用的&#8220;#&#8221;是虚连接。 <br />
方法四：用一个按钮调用： <br />
&lt;input type="button" onclick="openwin()" value="打开窗口"&gt; <br />
<br />
【4、同时弹出2个窗口】 <br />
<br />
对源代码稍微改动一下： <br />
<br />
&lt;script LANGUAGE="JavaScript"&gt; <br />
&lt;!-- <br />
function openwin() { <br />
window.open ("page.html", "newwindow", "height=100, width=100, top=0, left=0,toolbar=no, menubar=no, scrollbars=no, resizable=no, location=n o, status=no")//写成一行 <br />
window.open ("page2.html", "newwindow2", "height=100, width=100, top=1 00, left=100,toolbar=no, menubar=no, scrollbars=no, resizable=no, loca tion=no, status=no")//写成一行 <br />
} <br />
//--&gt; <br />
&lt;/script&gt; <br />
为避免弹出的2个窗口覆盖，用top和left控制一下弹出的位置不要相互覆盖即可 。最后用上面说过的四种方法调用即可。 <br />
注意：2个窗口的name(newwindows和newwindow2)不要相同，或者干脆全部为空。 <br />
<br />
【5、主窗口打开文件1.htm，同时弹出小窗口page.html】 <br />
<br />
如下代码加入主窗口&lt;head&gt;区： <br />
&lt;script language="javascript"&gt; <br />
&lt;!-- <br />
function openwin() { <br />
window.open("page.html","","width=200,height=200") <br />
} <br />
//--&gt; <br />
&lt;/script&gt; <br />
加入&lt;body&gt;区： <br />
&lt;a href="1.htm" onclick="openwin()"&gt;open&lt;/a&gt;即可。 <br />
<br />
【6、弹出的窗口之定时关闭控制】 <br />
<br />
下面我们再对弹出的窗口进行一些控制，效果就更好了。如果我们再将一小段 代码加入弹出的页面(注意是加入page.html的HTML中，不是主页面中)，让它10秒后自动关闭是不是更酷了？ <br />
首先，将如下代码加入page.html文件的&lt;head&gt;区： <br />
&lt;script language="JavaScript"&gt; <br />
function closeit() <br />
{ <br />
setTimeout("self.close()",10000) //毫秒 <br />
} <br />
&lt;/script&gt; <br />
然后 儆?lt;body onload="closeit()"&gt; 这一句话代替page.html中原有的&lt;BODY&gt;这一句就可以了。(这一句话千万不要忘记写啊！这一句的作用是调用关闭窗口的代码，10秒钟后就自行关闭该窗口。) <br />
<br />
【7、在弹出窗口中加上一个关闭按钮】 <br />
<br />
&lt;FORM&gt; <br />
&lt;INPUT TYPE='BUTTON' VALUE='关闭' onClick='window.close()'&gt; <br />
&lt;/FORM&gt; <br />
呵呵，现在更加完美了！ <br />
<br />
【8、内包含的弹出窗口-一个页面两个窗口】 <br />
<br />
上面的例子都包含两个窗口，一个是主窗口，另一个是弹出的小窗口。通过下面的例子，你可以在一个页面内完成上面的效果。 <br />
<br />
&lt;html&gt; <br />
&lt;head&gt; <br />
&lt;SCRIPT LANGUAGE="JavaScript"&gt; <br />
function openwin() <br />
{ <br />
OpenWindow=window.open("", "newwin", "height=250, width=250,toolbar=no ,scrollbars="+scroll+",menubar=no"); <br />
//写成一行 <br />
OpenWindow.document.write("&lt;TITLE&gt;例子&lt;/TITLE&gt;") <br />
OpenWindow.document.write("&lt;BODY BGCOLOR=#ffffff&gt;") <br />
OpenWindow.document.write("&lt;h1&gt;Hello!&lt;/h1&gt;") <br />
OpenWindow.document.write("New window opened!") <br />
OpenWindow.document.write("&lt;/BODY&gt;") <br />
OpenWindow.document.write("&lt;/HTML&gt;") <br />
OpenWindow.document.close() <br />
} <br />
&lt;/SCRIPT&gt; <br />
&lt;/head&gt; <br />
&lt;body&gt; <br />
&lt;a href="#" onclick="openwin()"&gt;打开一个窗口&lt;/a&gt; <br />
&lt;input type="button" onclick="openwin()" value="打开窗口"&gt; <br />
&lt;/body&gt; <br />
&lt;/html&gt; <br />
<br />
看看OpenWindow.document.write()里面的代码不就是标准的HTML吗？只要按照格式写更多的行即可。千万注意多一个标签或少一个标签就会出现错误。记得用 OpenWindow.document.close()结束啊。 <br />
<br />
【9、终极应用--弹出的窗口之Cookie控制】 <br />
<br />
回想一下，上面的弹出窗口虽然酷，但是有一点小毛病，比如你将上面的脚本放在一个需要频繁经过的页面里(例如首页)，那么每次刷新这个页面，窗口都会弹出一次，我们使用cookie来控制一下就可以了。 <br />
首先，将如下代码加入主页面HTML的&lt;HEAD&gt;区： <br />
<br />
&lt;script&gt; <br />
function openwin(){ <br />
window.open("page.html","","width=200,height=200") <br />
} <br />
function get_cookie(Name) { <br />
var search = Name + "=" <br />
var returnvalue = ""; <br />
if (document.cookie.length &gt; 0) { <br />
offset = document.cookie.indexOf(search) <br />
if (offset != -1) { <br />
offset += search.length <br />
end = document.cookie.indexOf(";", offset); <br />
if (end == -1) <br />
end = document.cookie.length; <br />
returnvalue=unescape(document.cookie.substring(offset, end)) <br />
} <br />
} <br />
return returnvalue; <br />
} <br />
function loadpopup(){ <br />
if (get_cookie('popped')==''){ <br />
openwin() <br />
document.cookie="popped=yes" <br />
} <br />
} <br />
&lt;/script&gt; <br />
<br />
然后，用&lt;body onload="loadpopup()"&gt;（注意不是openwin而是loadpop啊！）替换主页面中原有的&lt;BODY&gt;这一句即可。你可以试着刷新一下这个页面或重新进入该页面，窗口再也不会弹出了。真正的Pop-Only-Once！
<img src ="http://www.blogjava.net/junjie/aggbug/261955.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junjie/" target="_blank">wangjunjie</a> 2009-03-25 22:35 <a href="http://www.blogjava.net/junjie/archive/2009/03/25/261955.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多线程理解（转载）</title><link>http://www.blogjava.net/junjie/archive/2009/03/01/257223.html</link><dc:creator>wangjunjie</dc:creator><author>wangjunjie</author><pubDate>Sun, 01 Mar 2009 06:17:00 GMT</pubDate><guid>http://www.blogjava.net/junjie/archive/2009/03/01/257223.html</guid><wfw:comment>http://www.blogjava.net/junjie/comments/257223.html</wfw:comment><comments>http://www.blogjava.net/junjie/archive/2009/03/01/257223.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junjie/comments/commentRss/257223.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junjie/services/trackbacks/257223.html</trackback:ping><description><![CDATA[&nbsp;对于Java开发人员，多线程应该是必须熟练应用的知识点，特别是开发基于Java语言的产品。本文将深入浅出的表述Java多线程的知识点，在后续的系列里将侧重于Java5由Doug Lea教授提供的Concurrent并行包的设计思想以及具体实现与应用。<br />
&nbsp;&nbsp;&nbsp; 如何才能深入浅出呢，我的理解是带着问题，而不是泛泛的看。所以该系列基本以解决问题为主，当然我也非常希望读者能够提出更好的解决问题的方案以及提出更多的问题。由于水平有限，如果有什么错误之处，请大家提出，共同讨论，总之，我希望通过该系列我们能够深入理解Java多线程来解决我们实际开发的问题。<br />
&nbsp;&nbsp;&nbsp; 作为开发人员，我想没有必要讨论多线程的基础知识，比如什么是线程？ 如何创建等 ，这些知识点是可以通过书本和Google获得的。本系列主要是如何理深入解多线程来帮助我们平时的开发，比如线程池如何实现？ 如何应用锁等。&nbsp; <br />
<br />
（1）方法Join是干啥用的？ 简单回答，同步，如何同步？ 怎么实现的？ 下面将逐个回答。<br />
&nbsp;&nbsp;&nbsp; 自从接触Java多线程，一直对Join理解不了。JDK是这样说的：<br />
<!-- Generated by javadoc (build 1.6.0) on Wed Nov 29 02:21:27 PST 2006 -->
<link title="Style" href="/j2se6/api/stylesheet.css" type="text/css" rel="stylesheet" /><script type="text/javascript">
function windowTitle()
{
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="Thread (Java Platform SE 6)";
}
}
</script><noscript></noscript><script language="JScript" src="/j2se6/H2HHinclude.js"></script>&nbsp;&nbsp; join<br />
&nbsp;&nbsp;&nbsp; public final void <strong>join</strong>(long&nbsp;millis)throws <a title="class in java.lang" href="http://www.blogjava.net/j2se6/api/java/lang/InterruptedException.html">InterruptedException</a><br />
&nbsp;&nbsp;&nbsp; Waits at most <code>millis</code> milliseconds for this thread to die. A timeout of <code>0</code> means to wait forever.<br />
&nbsp;大家能理解吗？ 字面意思是等待一段时间直到这个线程死亡，我的疑问是那个线程，是它本身的线程还是调用它的线程的，上代码：&nbsp;<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;concurrentstudy;<br />
</span><span style="color: #008000">/**</span><span style="color: #008000"><br />
&nbsp;*<br />
&nbsp;*&nbsp;</span><span style="color: #808080">@author</span><span style="color: #008000">&nbsp;vma<br />
&nbsp;</span><span style="color: #008000">*/</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;JoinTest&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread&nbsp;t&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Thread(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;RunnableImpl());</span><span style="color: #008000"><br />
</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.join(</span><span style="color: #000000">1000</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">joinFinish</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(InterruptedException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;TODO&nbsp;Auto-generated&nbsp;catch&nbsp;block</span><span style="color: #008000"><br />
</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;RunnableImpl&nbsp;</span><span style="color: #0000ff">implements</span><span style="color: #000000">&nbsp;Runnable&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;run()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">Begin&nbsp;sleep</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(</span><span style="color: #000000">1000</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">End&nbsp;sleep</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(InterruptedException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</span></div>
结果是：<br />
Begin sleep<br />
End sleep<br />
joinFinish<br />
明白了吧，当main线程调用t.join时，main线程等待t线程，等待时间是1000，如果t线程Sleep 2000呢 <br />
<span style="color: #000000">&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;run()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">Begin&nbsp;sleep</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Thread.sleep(</span><span style="color: #000000">1000</span><span style="color: #000000">);<br />
</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.sleep(</span><span style="color: #000000">2000</span><span style="color: #000000">);</span><br />
<span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">End&nbsp;sleep</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(InterruptedException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</span><br />
结果是：<br />
Begin sleep<br />
joinFinish<br />
End sleep<br />
也就是说main线程只等1000毫秒，不管T什么时候结束，如果是t.join()呢， 看代码：&nbsp;&nbsp; <br />
&nbsp;public final void join() throws InterruptedException {<br />
&nbsp;&nbsp;&nbsp; join(0);<br />
&nbsp;&nbsp;&nbsp; }<br />
就是说如果是t.join() = t.join(0) 0　JDK这样说的 A timeout of <code>0</code> means to wait forever 字面意思是永远等待，是这样吗？<br />
其实是等到t结束后。<br />
这个是怎么实现的吗？ 看JDK代码：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">/**</span><span style="color: #008000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Waits&nbsp;at&nbsp;most&nbsp;&lt;code&gt;millis&lt;/code&gt;&nbsp;milliseconds&nbsp;for&nbsp;this&nbsp;thread&nbsp;to&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;die.&nbsp;A&nbsp;timeout&nbsp;of&nbsp;&lt;code&gt;0&lt;/code&gt;&nbsp;means&nbsp;to&nbsp;wait&nbsp;forever.&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080">@param</span><span style="color: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;millis&nbsp;&nbsp;&nbsp;the&nbsp;time&nbsp;to&nbsp;wait&nbsp;in&nbsp;milliseconds.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="color: #808080">@exception</span><span style="color: #008000">&nbsp;&nbsp;InterruptedException&nbsp;if&nbsp;any&nbsp;thread&nbsp;has&nbsp;interrupted<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;current&nbsp;thread.&nbsp;&nbsp;The&nbsp;&lt;i&gt;interrupted&nbsp;status&lt;/i&gt;&nbsp;of&nbsp;the<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current&nbsp;thread&nbsp;is&nbsp;cleared&nbsp;when&nbsp;this&nbsp;exception&nbsp;is&nbsp;thrown.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">*/</span><span style="color: #000000"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">final</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">synchronized</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;join(</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;millis)&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">throws</span><span style="color: #000000">&nbsp;InterruptedException&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;base&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;System.currentTimeMillis();<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;now&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(millis&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">throw</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;IllegalArgumentException(</span><span style="color: #000000">"</span><span style="color: #000000">timeout&nbsp;value&nbsp;is&nbsp;negative</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(millis&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">&nbsp;(isAlive())&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wait(</span><span style="color: #000000">0</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">&nbsp;(isAlive())&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">long</span><span style="color: #000000">&nbsp;delay&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;millis&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;now;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(delay&nbsp;</span><span style="color: #000000">&lt;=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">break</span><span style="color: #000000">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wait(delay);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;now&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;System.currentTimeMillis()&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;base;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
其实<strong>Join方法实现是通过<span style="color: #000000">wait（小提示：Object 提供的方法）。 当main线程调用t.join时候，main线程会获得线程对象t的锁（wait 意味着拿到该对象的锁),调用该对象的wait</span>(等待时间)，直到该对象唤醒main线程，比如退出后。</strong><br />
<br />
这就意味着main 线程调用t.join时，必须能够拿到线程t对象的锁，如果拿不到它是无法wait的，刚开的例子t.join(1000)不是说明了main线程等待1秒，如果在它等待之前，其他线程获取了t对象的锁，它等待时间可不就是1毫秒了。上代码介绍：<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #008000">/*</span><span style="color: #008000"><br />
&nbsp;*&nbsp;To&nbsp;change&nbsp;this&nbsp;template,&nbsp;choose&nbsp;Tools&nbsp;|&nbsp;Templates<br />
&nbsp;*&nbsp;and&nbsp;open&nbsp;the&nbsp;template&nbsp;in&nbsp;the&nbsp;editor.<br />
&nbsp;</span><span style="color: #008000">*/</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;concurrentstudy;<br />
</span><span style="color: #008000">/**</span><span style="color: #008000"><br />
&nbsp;*<br />
&nbsp;*&nbsp;</span><span style="color: #808080">@author</span><span style="color: #008000">&nbsp;vma<br />
&nbsp;</span><span style="color: #008000">*/</span><span style="color: #000000"><br />
</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;JoinTest&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;main(String[]&nbsp;args)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread&nbsp;t&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;Thread(</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;RunnableImpl());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ThreadTest(t).start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.join();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">joinFinish</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(InterruptedException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;TODO&nbsp;Auto-generated&nbsp;catch&nbsp;block</span><span style="color: #008000"><br />
</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;ThreadTest&nbsp;</span><span style="color: #0000ff">extends</span><span style="color: #000000">&nbsp;Thread&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;Thread&nbsp;thread;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;ThreadTest(Thread&nbsp;thread)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">.thread&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;thread;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;run()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;holdThreadLock();<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;holdThreadLock()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">synchronized</span><span style="color: #000000">&nbsp;(thread)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">getObjectLock</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(</span><span style="color: #000000">9000</span><span style="color: #000000">);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(InterruptedException&nbsp;ex)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ex.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">ReleaseObjectLock</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
<br />
</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;RunnableImpl&nbsp;</span><span style="color: #0000ff">implements</span><span style="color: #000000">&nbsp;Runnable&nbsp;{<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;run()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">Begin&nbsp;sleep</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(</span><span style="color: #000000">2000</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="color: #000000">"</span><span style="color: #000000">End&nbsp;sleep</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(InterruptedException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span></div>
<span style="color: #000000"><span style="color: #060000"><span style="color: #000000">在main方法中 </span><span style="color: #0000ff">通过new</span><span style="color: #000000">&nbsp;ThreadTest(t).start();实例化</span><span style="color: #000000">ThreadTest </span><span style="color: #0000ff">线程对象， 它在</span><span style="color: #000000">holdThreadLock()方法中，</span><span style="color: #000000">通过 </span><span style="color: #0000ff">synchronized</span><span style="color: #000000">&nbsp;(thread)</span>，获取线程对象t的锁，并Sleep（9000）后释放，这就意味着，即使<br />
main方法t.join(1000),等待一秒钟，它必须等待<span style="color: #000000">ThreadTest </span><span style="color: #0000ff">线程释放t锁后才能进入wait方法中，它实际等待时间是9000+1000 MS</span><br />
运行结果是：<br />
<span style="color: #0000ff">getObjectLock<br />
Begin sleep<br />
End sleep<br />
ReleaseObjectLock<br />
joinFinish<br />
<br />
小结：<br />
本节主要深入浅出join及ＪＤＫ中的实现。<br />
</span><span style="color: #0000ff"><a href="http://www.blogjava.net/vincent/archive/2008/08/24/223933.html">在下一节中，我们将要讨论SWing 中的事件方法线程来解决一个网友问到的问题：</a><br />
如何控制Swing程序在单机只有一个实例，也就是不能运行第二个Main方法。</span></span></span><span style="color: #0000ff"><br />
<br />
</span>
<img src ="http://www.blogjava.net/junjie/aggbug/257223.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junjie/" target="_blank">wangjunjie</a> 2009-03-01 14:17 <a href="http://www.blogjava.net/junjie/archive/2009/03/01/257223.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转载 Soalries中常用命令</title><link>http://www.blogjava.net/junjie/archive/2009/02/15/254789.html</link><dc:creator>wangjunjie</dc:creator><author>wangjunjie</author><pubDate>Sun, 15 Feb 2009 11:24:00 GMT</pubDate><guid>http://www.blogjava.net/junjie/archive/2009/02/15/254789.html</guid><wfw:comment>http://www.blogjava.net/junjie/comments/254789.html</wfw:comment><comments>http://www.blogjava.net/junjie/archive/2009/02/15/254789.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junjie/comments/commentRss/254789.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junjie/services/trackbacks/254789.html</trackback:ping><description><![CDATA[<h3><span style="font-family: 宋体">系统基本配置</span> </h3>
<p><span style="font-family: 宋体">如何查看日志信息</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dmesg | more /var/adm/messages*&nbsp;&nbsp;&nbsp; </p>
<p><span style="font-family: 宋体">收集</span> exlpore <span style="font-family: 宋体">日志</span> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /opt/SUNWexplo/bin/explorer -k -&gt;/opt/SUNWexplo/output </p>
<p><span style="font-family: 宋体">系统的基本状况</span> &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; showrev&nbsp;</p>
<p><span style="font-family: 宋体">系统运行时间，平均负载</span> &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; uptime&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; </p>
<p><span style="font-family: 宋体">版本信息</span> &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; uname -a&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; </p>
<p>Update <span style="font-family: 宋体">版本</span> &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; more /etc/release&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p><span style="font-family: 宋体">系统补丁</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; showrev -p&nbsp;<span style="font-family: 宋体">已安装的补丁信息</span> &nbsp;patchadd 123-12 <span style="font-family: 宋体">打补丁</span> </p>
<p><span style="font-family: 宋体">查看服务对应的端口</span> &nbsp;more /etc/services </p>
<p><span style="font-family: 宋体">系统变量设置</span> env <span style="font-family: 宋体">，</span> sysdef </p>
<p>Shell <span style="font-family: 宋体">变量：</span> bash,csh,ksh </p>
<p><span style="font-family: 宋体">收集</span> explore <span style="font-family: 宋体">日志</span> </p>
<p style="margin-left: 21pt"><span style="font-family: 宋体">先查看有没有装</span> <br />
# pkginfo |grep SUNWexplo<br />
<span style="font-family: 宋体">如果有安装的话：</span> <br />
# /opt/SUNWexplo/bin/explorer<br />
<span style="font-family: 宋体">收集到的文件在：</span> <br />
# /opt/SUNWexplo/output </p>
<p><span style="font-family: 宋体">清空日志：</span> cp /var/adm/messages /var/adm/messages.bkp &nbsp;#cat /dev/null &gt; /var/adm/messages </p>
<h3><span style="font-weight: normal; font-family: 'Calibri','sans-serif'">CPU</span> &nbsp; </h3>
<p>psrinfo -vp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">系统</span> cpu <span style="font-family: 宋体">数和速度</span> </p>
<p>uptime&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cpu <span style="font-family: 宋体">平均负载</span> </p>
<p>prstat -a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">实时进程的状态</span> </p>
<p>ps -ef&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">显示所有进程的详细信息</span> </p>
<p>kill pid <span style="font-family: 宋体">杀死进程</span> </p>
<p>vmstat <span style="font-family: 宋体">，</span> mpstat <span style="font-family: 宋体">，</span> /usr/ucb/ps -aux </p>
<h3><span style="font-family: 宋体">内存</span> </h3>
<p>prtdiag -v <span style="font-family: 宋体">系统硬件，电源接口等</span> </p>
<p><span style="font-family: 宋体">查看内存大小</span> prtconf -vp | grep Mem </p>
<p>vmstat </p>
<p>swap -s </p>
<p><span style="font-family: 宋体">增加</span> swap <span style="font-family: 宋体">分区：</span> mkfile 200m /tmp ,swap -a,swap -l </p>
<p>C5292 </p>
<h3><span style="font-family: 宋体">磁盘管理</span> </h3>
<p>iostat&nbsp;<span style="font-family: 宋体">监视系统输入／输出设备负载</span> </p>
<p>format&nbsp;<span style="font-family: 宋体">系统几块磁盘，大小</span> Ctrl+D <span style="font-family: 宋体">的组合键退出</span> </p>
<p>metastat <span style="font-family: 宋体">显示硬盘</span> raid <span style="font-family: 宋体">状态</span> </p>
<p><span style="font-family: 宋体">检查硬盘信息</span> prtvtoc /dev/dsk/c0t0d0s5 </p>
<p><span style="font-family: 宋体">查看</span> NBU <span style="font-family: 宋体">硬盘</span> available_media </p>
<p><span style="font-family: 宋体">如何添加硬盘</span> </p>
<p style="text-indent: 21pt">1 <span style="font-family: 宋体">，</span> mkdir /usr/ldap3</p>
<p style="text-indent: 21pt">2 <span style="font-family: 宋体">，</span> newfs /dev/rdsk/c1t3d0s1&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3 <span style="font-family: 宋体">，</span> mount /dev/dsk/c1t3d0s1 /usr/ldap3 </p>
<p style="text-indent: 21pt">4 <span style="font-family: 宋体">，</span> vi /etc/vfstab <span style="font-family: 宋体">添加文件系统信息</span> </p>
<p style="text-indent: 21pt">/dev/dsk/c1t2d0s0 &nbsp;/dev/rdsk/c1t2d0s0&nbsp;&nbsp; /usr/ldap3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ufs&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;yes&nbsp;&nbsp;&nbsp;&nbsp; logging<br />
&nbsp;</p>
<h3><span style="font-family: 宋体">文件系统</span> </h3>
<p>df -k&nbsp;&nbsp; <span style="font-family: 宋体">磁盘使用情况</span> </p>
<p><span style="font-family: 宋体">磁带机的读存数据</span> : tar cpio </p>
<p><span style="font-family: 宋体">磁带机状态</span> &nbsp;mt -f /dev/rmt/0 status </p>
<p><span style="font-family: 宋体">虚拟文件系统表</span> &nbsp;/etc/vfstab </p>
<p>Solaris <span style="font-family: 宋体">硬盘分区</span> </p>
<h3><span style="font-family: 宋体">网络</span> </h3>
<p>ping <span style="font-family: 宋体">，</span> netstat -arp <span style="font-family: 宋体">，</span> </p>
<p>ifconfig &#8211;a </p>
<h3><span style="font-family: 宋体">系统基本操作</span> </h3>
<h3><span style="font-family: 宋体">文件操作</span> </h3>
<p><span style="font-family: 宋体">压缩解压</span> tar gzip gunzip </p>
<p>iso <span style="font-family: 宋体">文件</span> &nbsp;lofiadm </p>
<p><span style="font-family: 宋体">查看文件信息</span> &nbsp;ls -lrt </p>
<p><span style="font-family: 宋体">目录大小</span> &nbsp;du -sk dir </p>
<p>mkdir ,cd, </p>
<p><span style="font-family: 宋体">查找文件：</span> Find&nbsp;<span style="font-family: 宋体">文件类型</span> file </p>
<p><span style="font-family: 宋体">查看文件</span> more <span style="font-family: 宋体">，</span> head <span style="font-family: 宋体">，</span> tail <span style="font-family: 宋体">，</span> cat <span style="font-family: 宋体">例如：</span> tail -10 /var/adm/messages </p>
<p><span style="font-family: 宋体">文件的权限</span> chmod: chmod 644 a.txt&nbsp;</p>
<p><span style="font-family: 宋体">解包</span> tar vcf filename.tar </p>
<p><span style="font-family: 宋体">打包</span> tar cvf filename.tar dirname </p>
<p>.gz <span style="font-family: 宋体">文件</span> <span style="font-family: 宋体">解压</span> gunzip filename.gz ; gzip -d filename.gz &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">压缩</span> gzip filenam </p>
<p>.tar.gz&nbsp;<span style="font-family: 宋体">解压：</span> tar zxcf file.tar.gz&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; <span style="font-family: 宋体">压缩；</span> tar zcvf file.tar.gz dirname </p>
<p><span style="font-family: 宋体">创建和编辑文件：</span> </p>
<p><span style="font-family: 宋体">生成新文件或改变文件日期：</span> Touch &nbsp; <span style="font-family: 宋体">文件拷贝</span> cp <span style="font-family: 宋体">移动文件</span> mv </p>
<p><span style="font-family: 宋体">修改文件：</span> vi<span style="font-family: 宋体">的用法</span></p>
<p><span style="font-family: 宋体">组合命令</span> : <span style="font-family: 宋体">；</span> <span style="font-family: 宋体">输出重定向</span> &gt;&nbsp;&nbsp; <span style="font-family: 宋体">组合命令</span> | </p>
<p><span style="font-family: 宋体">常用管理命令</span> man </p>
<h3><span style="font-family: 宋体">用户管理</span> </h3>
<p>groupadd <span style="font-family: 宋体">，</span> useradd <span style="font-family: 宋体">，</span> passwd </p>
<p><span style="font-family: 宋体">查看用户</span> / <span style="font-family: 宋体">组</span> more /etc/passwd <span style="font-family: 宋体">，</span> /etc/shadow <span style="font-family: 宋体">，</span> /etc/group </p>
<p>(who <span style="font-family: 宋体">、</span> finger <span style="font-family: 宋体">、</span> rusers <span style="font-family: 宋体">－</span> 1 <span style="font-family: 宋体">、</span> whodo <span style="font-family: 宋体">、</span> id </p>
<p><strong><span style="font-family: 宋体">如何做系统硬件健康状况检查</span> </strong></p>
<p># more /var/adm/messages* <span style="font-family: 宋体">（没有重大异常报错）</span> </p>
<p># df &#8211;k (&#8220;/&#8221; <span style="font-family: 宋体">使用率小于</span> 85%) </p>
<p># format <span style="font-family: 宋体">（</span> ctrl+d<span style="font-family: 宋体">退出）（所有硬盘正常）</span></p>
<p># prtdiag &#8211;v ( <span style="font-family: 宋体">没有</span> failed <span style="font-family: 宋体">的部件、内存和</span> cpu <span style="font-family: 宋体">数量正确</span> ) </p>
<p># psrinfo &#8211;v ( <span style="font-family: 宋体">系统中所有的</span> cpu <span style="font-family: 宋体">都处在</span> online <span style="font-family: 宋体">状态</span> ) </p>
<p><strong><span style="font-family: 宋体">运行级别</span> </strong></p>
<p><span style="font-family: 宋体">查看系统的运行级、日期及时间</span> &nbsp; who&nbsp;&nbsp; &#8211;r </p>
<p><span style="font-family: 宋体">系统运行级别</span> 1 <span style="font-family: 宋体">、</span> <span style="font-family: 宋体">掉电（运行级</span> 0 <span style="font-family: 宋体">）</span> 2 <span style="font-family: 宋体">、</span> <span style="font-family: 宋体">单用户（运行级</span> 1 <span style="font-family: 宋体">和</span> s <span style="font-family: 宋体">或</span> S <span style="font-family: 宋体">）</span> </p>
<p>3 <span style="font-family: 宋体">、</span> <span style="font-family: 宋体">多用户（运行级</span> 2 <span style="font-family: 宋体">和</span> 3 <span style="font-family: 宋体">）</span> 4 <span style="font-family: 宋体">、</span> <span style="font-family: 宋体">重引导（运行级</span> 5 <span style="font-family: 宋体">和</span> 6 <span style="font-family: 宋体">）</span> </p>
<p><span style="font-family: 宋体">重新启动</span> &nbsp;reboot, init 6 </p>
<p><span style="font-family: 宋体">关闭系统：</span> shutdown <span style="font-family: 宋体">，</span> init 0 <span style="font-family: 宋体">，</span> halt </p>
<h2><span style="font-family: 宋体">其它管理</span> </h2>
<p><span style="font-family: 宋体">定时任务</span> </p>
<p><span style="font-family: 宋体">将</span> crontab&nbsp; <span style="font-family: 宋体">推到一个自定义的文件上</span> <br />
crontab&nbsp;-l&gt;tmp <br />
<span style="font-family: 宋体">编辑这个文件，做需要的修改</span> <br />
vi&nbsp;tmp <br />
<span style="font-family: 宋体">推回</span> crontab <br />
crontab&nbsp;tmp </p>
<h3>NBU <span style="font-family: 宋体">备份</span> </h3>
<p>#bpdbjobs &#8211;report&nbsp;&nbsp; <span style="font-family: 宋体">检查作业备份情况，返回为</span> 0 <span style="font-family: 宋体">即为正常</span> </p>
<p>#bpps &#8211;a&nbsp;&nbsp; <span style="font-family: 宋体">备份进程启动情况</span> </p>
<h3><span style="font-family: 宋体">磁盘阵列管理</span> </h3>
<p>&nbsp;#sccli </p>
<p>sccli: selected device /dev/rdsk/c2t0d0s2 [SUN StorEdge yyyy SN#08472F] </p>
<p>#sccli&gt; show disks </p>
<p><span style="font-family: 宋体">输出的</span> Status <span style="font-family: 宋体">列，所有值正常情况下是</span> &#8221; ONLINE&#8221; <span style="font-family: 宋体">或</span> &#8221; STAND-BY&#8221; <span style="font-family: 宋体">，其它的值都是不正常的；</span> </p>
<p>#sccli&gt; show logical-drives </p>
<p><span style="font-family: 宋体">输出的</span> Status <span style="font-family: 宋体">列，其值正常情况下是</span> &#8221; Good&#8221; <span style="font-family: 宋体">，其它的值都是不正常的；</span> </p>
<p>#sccli&gt;show enclosure-status </p>
<p><span style="font-family: 宋体">输出的</span> Status <span style="font-family: 宋体">列，所有值正常情况下是</span> &#8221; OK&#8221; <span style="font-family: 宋体">或者</span> &#8221; Absent&#8221; <span style="font-family: 宋体">，其它的值都是不正常的；</span> </p>
<p>#sccli&gt;show FRUs </p>
<p><span style="font-family: 宋体">输出的</span> FRU Status <span style="font-family: 宋体">行，所有值正常情况下是</span> &#8221;OK&#8221; <span style="font-family: 宋体">，</span> <span style="font-family: 宋体">其它的值都是不正常的；</span> </p>
<p>#sccli&gt; show peripheral-device-status </p>
<p><span style="font-family: 宋体">输出的</span> status <span style="font-family: 宋体">列，所有值正常情况下是</span> &#8221;within safety range&#8221; <span style="font-family: 宋体">或</span> &#8221; N/A&#8221; <span style="font-family: 宋体">或</span> &#8221; Hardware:N/A&#8221; <span style="font-family: 宋体">或</span> &#8221; Hardware:OK&#8221; <span style="font-family: 宋体">，</span> <span style="font-family: 宋体">其它的值都是不正常的；</span> </p>
<p>#sccli&gt;exit </p>
<p>oracle </p>
<p>lsnrctl status <span style="font-family: 宋体">查看</span> listener <span style="font-family: 宋体">进程的状态</span> </p>
<p>tnsping SID&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">查看连通请款</span> </p>
<p>sun cluster </p>
<p>scinstall -pv&nbsp;<span style="font-family: 宋体">版本信息</span> </p>
<p>luxadm -e port <span style="font-family: 宋体">光纤链路状态</span> </p>
<img src ="http://www.blogjava.net/junjie/aggbug/254789.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junjie/" target="_blank">wangjunjie</a> 2009-02-15 19:24 <a href="http://www.blogjava.net/junjie/archive/2009/02/15/254789.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SQL高级查询（转载）</title><link>http://www.blogjava.net/junjie/archive/2008/12/19/247325.html</link><dc:creator>wangjunjie</dc:creator><author>wangjunjie</author><pubDate>Fri, 19 Dec 2008 05:57:00 GMT</pubDate><guid>http://www.blogjava.net/junjie/archive/2008/12/19/247325.html</guid><wfw:comment>http://www.blogjava.net/junjie/comments/247325.html</wfw:comment><comments>http://www.blogjava.net/junjie/archive/2008/12/19/247325.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junjie/comments/commentRss/247325.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junjie/services/trackbacks/247325.html</trackback:ping><description><![CDATA[<div>
<p>transact---sql高级查询（下）<br />
5:使用having关键字来筛选结果<br />
6:使用compute和compute by子句<br />
7:使用嵌套查询<br />
8:分布式查询</p>
<p>E:使用having关键字来筛选结果<br />
&nbsp;&nbsp;&nbsp; 当完成对数据结果的查询和统计后,可以使用having关键字来对查询和计算的结果进行一步的筛选<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 例:检索出work表中学历是大专或者是中专的人数<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select 学历,count(学历) from work group by 学历 having 学历 in("'大专"',"'中专"')<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 说明:1:having关键字都与group by用在一起.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2:having不支持对列分配的别名<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 例如:select 学历,"'大于5的人数"'=count(学历) from work group by 学历 having 大于5的人数&gt;5 [错错]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 改为:select 学历,"'大于5的人数"'=count(学历) from work group by 学历 having count(学历)&gt;5</p>
<p>F:使用compute和compute by<br />
&nbsp; 使用compute子句允许同时观察查询所得到各列的数据的细节以及统计各列数据所产生的汇总列<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select * from work [查询所得到的各列的数据的细节]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; compute max(基本工资),min(基本工资) [统计之后的结果]<br />
&nbsp; 这个例子中没有使用by关键字,返回的结果是最后添加了一行基本工资的最大值和最小值,也可增加by关键字.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 例:select * from work order by 学历<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; compute max(基本工资),min(基本工资) by 学历<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 比较:select 学历,max(基本工资),min(基本工资) from work group by 学历<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 说明:1:compute子句必须与order by子句用在一起<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2:compute子句可以返回多种结果集.一种是体现数据细节的数据集,可以按分类要求进行正确的分类；另一种在分类的基础上进行汇总产生结果.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3:而group by子句对每一类数据分类之后只能产生一个结果,不能知道细节</p>
<p>G:使用嵌套查询<br />
&nbsp; 查询中再查询,通常是以一个查询作为条件来供另一个查询使用<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 例:有work表和部门表<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A:检索出在部门表中登记的所有部门的职工基本资料<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select * from work where 部门编号 in [not in](select 部门编号 from dbo.部门) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B:检索出在work表中每一个部门的最高基本工资的职工资料<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select * from work a where 基本工资=(select max(基本工资) from work b where a.部门名称=b.部门名称) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 说明:由外查询提供一个部门名称给内查询,内查询利用这个部门名称找到该部门的最高基本工资,然后外查询根据基本工资判断是否等于最高工资,如果是的,则显示出来.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 相当于:select * from work,(select 部门名称,max(基本工资) as 基本工资 from work group by 部门名称 as t) where work.基本工资=t.基本工资 and work.部门名称=t.部门名称<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C:用嵌套work表和嵌套部门表,在嵌套work表中检索出姓名和职工号都在嵌套部门存在的职工资料 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select * from 嵌套work where 职工号 in (select 职工号 from 嵌套部门) and 姓名 in (select 姓名 from 嵌套部门) [察看结果,分析原因] <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 改:select * from 嵌套work a,嵌套部门 b where a.职工号=b.职工号 and a.姓名=b.姓名 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 改:select * from 嵌套work where 职工号=(select 职工号 from 嵌套部门) and 姓名=(select 姓名 from 嵌套部门) [行吗?为什么,分析原因?] </p>
<p>在嵌套中使用exists关键字[存在]<br />
例:1:用嵌套work表和嵌套部门表,在嵌套work表中检索出姓名和职工号都在嵌套部门存在的职工资料 <br />
&nbsp;&nbsp;&nbsp;&nbsp; select * from 嵌套work a where exists (select * from 嵌套部门 b where a.姓名=b.姓名 and a.职工号=b.职工号)<br />
&nbsp;&nbsp; 2:在work表检索出在部门表没有的职工<br />
&nbsp;&nbsp;&nbsp;&nbsp; select * from work where not exists (select * from 部门 where 部门.部门编号=work.部门编号)<br />
&nbsp;&nbsp;&nbsp;&nbsp; 能否改成:select * from work where exists (select * from 部门 where 部门.部门编号&lt;&gt;work.部门编号)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
在列清单中使用select<br />
例:1:在work1表和部门表中检索出所有部门的部门名称和基本工资总和<br />
&nbsp;&nbsp;&nbsp; select 部门名称,(select sum(基本工资) from work1 b where a.部门编号=b.部门编号) from 部门 a<br />
&nbsp;&nbsp; 2:检索各部门的职工人数<br />
&nbsp;&nbsp;&nbsp; select 部门编号,部门名称,(select count(职工号) from work1 a where a.部门编号=b.部门编号) as 人数 from 部门 b<br />
&nbsp;&nbsp; 3:在商品表和销售表中查询每一职工的姓名,所属部门,销售总量&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; select 姓名,所属部门,(select sum(销售量) from 商品销售 a where a.职工号=b.职工号) as 销售总量 from 嵌套部门 b</p>
<p>H:分布式查询<br />
我们以前的查询都只是基于一个服务器中的一个数据库的查询,如果一个查询是要跨越一个服务器,像这样的查询就是分布式查询,那么我们以看到分布查询就是数据源自于两个服务器.要进行分布式查询必须先创建一个&#8220;链接服务器&#8221;,以便让本地的用户能够映射到过程服务器.<br />
&#8220;链接服务器&#8221;的创立<br />
&nbsp;&nbsp;&nbsp;&nbsp; A:在&#8220;链接服务器&#8221;里面输入以后为了方便访问该链接服务器的名称[任意]<br />
&nbsp;&nbsp;&nbsp;&nbsp; B:在&#8220;提供程序名称&#8221;里面选择&#8220;Microsoft OLE DB Provider for SQL Server&#8221;<br />
&nbsp;&nbsp;&nbsp;&nbsp; C:在&#8220;数据源&#8221;里面输入服务器的网络名<br />
&nbsp;&nbsp;&nbsp;&nbsp; D:本地登录,远程用户和远程密码里面分别输入一个本地登录用户,远程登录和远程密码以便让本地SQL Server登录映射为链接服务器上的用户<br />
&nbsp;&nbsp;&nbsp;&nbsp; E:访问方法:格式:链接服务器的名称.数据库名.dbo.表名<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 链接服务器有两个特点:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1:通过链接服务器不能删除链接源服务器的任何对像.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2:能过链接服务器可以对链接源服务器的表进行insert,updae,delete操作.</p>
<p>&nbsp;</p>
<p><br />
视图<br />
1:什么是视图<br />
2:视图和查询的区别<br />
3:视图的优点<br />
4:如何创建和管理视图<br />
5:如何通过视图修改基本表的数据<br />
6:如何通过视图实现数据的安全性</p>
<p>A:什么是视图:<br />
视图(view):从一个或几个基本表中根据用户需要而做成一个虚表<br />
&nbsp;&nbsp;&nbsp; 1:视图是虚表,它在存储时只存储视图的定义,而没有存储对应的数据<br />
&nbsp;&nbsp;&nbsp; 2:视图只在刚刚打开的一瞬间,通过定义从基表中搜集数据,并展现给用户 </p>
<p>B:视图与查询的区别: <br />
视图和查询都是用由sql语句组成,这是他们相同的地方,但是视图和查询有着本质区别:<br />
它们的区别在于:1:存储上的区别:视图存储为数据库设计的一部分,而查询则不是.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2:更新限制的要求不一样<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 要注意:因为视图来自于表,所以通过视图可以间接对表进行更新,我们也可以通过update语句对表进行更新,但是对视图和查询更新限制是不同的,以下我们会知道虽然通过视图可以间接更新表但是有很多限制.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3:排序结果:通过sql语句,可以对一个表进行排序,而视图则不行.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 比如:创建一个含有order by子句的视图,看一下可以成功吗?</p>
<p>C:视图的优点:&nbsp; <br />
为什么有了表还要引入视图呢？这是因为视图具有以下几个优点:<br />
1:能分割数据,简化观点<br />
&nbsp; 可以通过select和where来定义视图,从而可以分割数据基表中某些对于用户不关心的数据,使用户把注意力集中到所关心的数据列.进一步简化浏览数据工作.<br />
2:为数据提供一定的逻辑独立性<br />
&nbsp; 如果为某一个基表定义一个视图,即使以后基本表的内容的发生改变了也不会影响&#8220;视图定义&#8221;所得到的数据<br />
3:提供自动的安全保护功能<br />
&nbsp; 视图能像基本表一样授予或撤消访问许可权.<br />
4:视图可以间接对表进行更新,因此视图的更新就是表的更新</p>
<p>D:视图的创建和管理<br />
&nbsp; 视图的创建<br />
&nbsp; 1:通过sql语句<br />
&nbsp;&nbsp;&nbsp; 格式:create view 视图名 as select 语句<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 试一试:分别创建关于一个表或多个表的视图[因为视图可以来自于多表]<br />
&nbsp; 2:通过企业管理器&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 说明:1:在完成视图的创立之后,就可以像使用基本表一样来使用视图<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2:在创建视图时,并非所有的select子查询都可用<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如:compute和compute by,order by[除非与top一起连用]&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3:但在查询时,依然都可以用在创建时禁用的select子查询<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4:在视图创建时,必须为没有标题列指定标题[思考:能否不用select语句来创建一个视图]<br />
&nbsp; <br />
&nbsp; 视图的删除:<br />
&nbsp; 1:通过sql语句:drop view 视图名<br />
&nbsp; 2:通过企业管理器<br />
&nbsp;&nbsp;&nbsp; 说明:与删除表不同的是,删除视图后只是删除了视图了定义,并没有删除表中的数据.[查看相关性]<br />
&nbsp; <br />
&nbsp; 修改视图的定义<br />
&nbsp; 1:通过企业管理器<br />
&nbsp; 2:通过sql语句:<br />
&nbsp;&nbsp;&nbsp; 格式:alter view 视图名 as 新的select语句</p>
<p>浏览视图信息 sp_helptext 视图名 [查看视图创建的语句] </p>
<p>E:如何通过视图修改基本表的数据.<br />
&nbsp; 1:在视图上使用insert语句<br />
&nbsp;&nbsp;&nbsp; 通过视图插入数据与直接在表中插入数据一样,但视图毕竟不是基本表.因此在进行数据插入时还是有一定的限制<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1:如果视图上没有包括基本表中属性为not null[不能为空]的列,那么插入操作会因为那些列是null值而失败.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2:如果某些列因为某些规则或约束的限制而不能直接接受从视图插入的列时,插入会失败<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3:如果在视图中包含了使用统计函数的结果,或是包含计算列,则插入操作会失败<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4:不能在使用了distinct语句的视图中插入值<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5:不能在使用了group by语句的视图中插入值</p>
<p>&nbsp; 2:使用update更新视图中的数据<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1:更新视图与更新表格一样,但是在视图中使用了多个基本表连接的情况下,每次更新操作只能更新来自基本表的一个数据列<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 例如:创建以下视图:create view del as <br />
&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; select 职工号,姓名,部门名称,负责人 from work1,部门 <br />
&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; where work1.部门编号=部门.部门编号<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果再执行下面的语句时:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; update del set 职工号="'001"',部门名称="'wenda"' where 职工号="'01"'[出现错误]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 只能够改成:update del set 职工号="'001"' where 职工号="'01"' <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; update del set 部门名称="'wenda"' where 职工号="'01"' <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2:不能在使用了distinct语句的视图中更新值<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3:不能在使用了group by语句的视图中更新值<br />
&nbsp; <br />
&nbsp; 3:使用delete删除视图中数据.<br />
&nbsp;&nbsp;&nbsp; 通过视图删除数据最终体现为从基本表中删除数据<br />
&nbsp;&nbsp;&nbsp; 格式:delete 视图名 [where 条件]<br />
&nbsp;&nbsp;&nbsp; 说明:当视图由两个以上的基表构成时,不允许删除视图的数据 <br />
&nbsp;&nbsp;&nbsp; 例如:建一个视图kk<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; create view kk as <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select 职工号,姓名,性别,部门名称 from work1,部门 where work1.部门编号=部门.部门编号 [试着去删除]</p>
<p>&nbsp;&nbsp;&nbsp; 使用with check option的视图<br />
&nbsp;&nbsp;&nbsp; 如果不了解视图定义内容,则常常会发生向视图中输入不符合视图定义的数据的情况.<br />
&nbsp;&nbsp;&nbsp; 比如:create view xm as <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select * from work where 性别="'男"'<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 完全可以插入insert xm values("'001"',"'女"',23,"'2400"'....)<br />
尽管从意义上来说是不合理的,但是上述语句是正确的.为了防止这种情况的发生,可以使用with check option子句来对插入的或更改的数据进行限制.<br />
&nbsp;&nbsp;&nbsp; 比如:create view xm as <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; select * from work where 性别="'男"' with check option</p>
<p>&nbsp;&nbsp;&nbsp; 使用schemabinding的视图[使用绑定到构架]<br />
我们知道视图是依赖于表,如果在一个表中创建一个视图,今后如果这个表被删除了,则这个视图将不可再用了.为了防止用户删除一个有视图在引用的表,可以在创建视图的时候加上schemabinding关键字.<br />
&nbsp;&nbsp;&nbsp; 比如:create view 基本工资 with SCHEMABINDING<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; as select 姓名,性别,基本工资 from dbo.work <br />
&nbsp;&nbsp;&nbsp; 说明:1:不能使用&#8220;*&#8221;来创建此类型的视图<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2:创建此类型的视图时,一定要加上dbo.表名.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3:如果在某个表中定义了此类视图,则用户将不能对表的结构进行修改,否则会删除这些绑定<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4:如果用户对表的结构进行列改名,则会删除绑定而且视图不可用.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5:如果用户对表的结构进行列的类型或者大小修改,则会删除绑定但视图可用,此时用户可以删除视图所引用的表.<br />
&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; 使用with encryption对视图进行加密<br />
为了保护创建视图定义的原代码,可以对视图进行加密.<br />
&nbsp;&nbsp;&nbsp; 比如:create view kk with encryption <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; as select * from work where 职称="'经理"' <br />
&nbsp;&nbsp;&nbsp; 用sp_helptext来查看一下.或用企业管理器查看一下.<br />
&nbsp;&nbsp;&nbsp; 说明:如果应用此项用户将无法设计视图</p>
<p>F:使用视图加强数据的安全<br />
&nbsp; 一般通过使用视图共有三种途径加强数据的安全性&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp; A:对不同用户授予不同的使用权.<br />
&nbsp;&nbsp;&nbsp;&nbsp; B:通过使用select子句限制用户对某些底层基表的列的访问<br />
&nbsp;&nbsp;&nbsp;&nbsp; C:通过使用where子句限制用户对某些底层基表的行的访问<br />
&nbsp; 对不同用户授予不同的权限</p>
</div>
<img src ="http://www.blogjava.net/junjie/aggbug/247325.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junjie/" target="_blank">wangjunjie</a> 2008-12-19 13:57 <a href="http://www.blogjava.net/junjie/archive/2008/12/19/247325.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>操作数据库应该养成的好习惯（转载）</title><link>http://www.blogjava.net/junjie/archive/2008/12/19/247317.html</link><dc:creator>wangjunjie</dc:creator><author>wangjunjie</author><pubDate>Fri, 19 Dec 2008 05:18:00 GMT</pubDate><guid>http://www.blogjava.net/junjie/archive/2008/12/19/247317.html</guid><description><![CDATA[<p>我们开发的系统中，数据是最重要的一部分，如果程序的代码错了，我们可以通过各种方式修改回来，但如果数据失真了，将永远无法还原，那种欲哭无泪的滋味，相信经历过的人是深有体会的。可能这些小的细节对我们来说都是微不足道的，但往往这些微不足道而且是小概率的事件将会毁了你。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 记得刚开始工作的时候，我们项目组的几个人对某个市的数据进行操作，由于自己的一个不小心，写错了一个SQL就把其中一部分的数据给毁了，那时候心理真的很难受，多么希望有个人可以骂骂我，至少心理会好受一点，但是没有人理我，这样一直在水深火热这中，感觉自己已经到了地狱一般。经过多年程序生涯，在地狱中也得到了一些成长，于是把自己的一点用金钱换来的经验全盘托出，希望对一些朋友有所帮助。<br />
<br />
<br />
<br />
<br />
1、不要用Truncate Table语句。刚开始学这个语句的时候，相信很多人多会拿出来跑一跑，会很高兴地向同事证明你的Truncate Table比Delete跑得更快，但是如果你养成这样的习惯，万一有一天误删东西的时候，就还原不回来了，因为Truncate Table不会记录日志，所以，如果操作重要数据的时候，还是用回Delete语句吧。<br />
<br />
2、每次动数据库之前，都先要把数据库备份起来。这个习惯一定要养成，你操作数据库的时候，哪怕只是做一次简单的查询或只是删除几条普通的数据，都先备份一下，不会花你很多时间，却在你失误的时候可以把你从死亡的边缘拉回来。如果数据比较大，至少也要把表里的数据备份出来。<br />
<br />
3、把删除语句以及更新语句、插入语句注释掉。我们操作数据库时，通常都喜欢在查询分析器里写一大堆SQL，然后选择某一条，按F5来执行，但有时候会直接按下F5，导致所有的语句都执行，给数据造成一定的损害。如果你把那些有影响的语句注释掉了，就算按错了也没有关系。<br />
<br />
<br />
4、不要随便地去分离数据库。如果我们要获取整个数据库的数据时，尽量采用把数据备份下来，然后取到其他机器上还原，而不要把数据库分离，然后再复制到其它机器附加。有时候，数据库分离了之后就会造成无法附加，虽然概率很小，但一旦碰上了就会很麻烦，尤其是一些实时的系统。<br />
<br />
5、自己不熟悉的数据库，不要去动它。我们维护数据库时，有时候要 出差到其他市去操作数据，这时，其他项目组的同事可能会叫你帮忙更新这个更新那个的，如果你很熟悉数据库的结构，以及了解更新的影响程度，那么你帮忙操作就无所谓，如果你不熟悉，尽量不操作，如果你做好了，功劳不是你的，如果出了什么差错，你就要背黑锅了。<br />
<br />
6、身体疲劳时不要操作数据库。加班是程序员的家常便饭，当你加班到身体很疲劳时，操作数据库失误的概率会很大，我记得刚刚出来工作时有一次我写了一个DELETE语句，选择执行了居然漏选了一个WHERE条件，还好数据比较多，超时了，要不然就.........<br />
<br />
7、如果自己对数据库结构了解很透彻，而且你的数据库技术水平已经达到一定的高度，更加要小心了，通常出现误操作导致数据失真就是这个阶段，有时候学了一个新语法就会马上拿去试着使用。<br />
<br />
8、经常要考虑你的SQL脚本有没有什么漏洞，或者有没有其他方法可以更有效率地执行。<br />
<br />
<br />
9、SQL SERVER2000里面有一个宝藏，就是它的联机丛书，建议经常去阅读它，当你把它读完并理解之后，你的SQL水平基本就可以超80%的程序员了，根本不要去迷信什么NB的教材，但到了那个时候，你会发现自己懂的东西少了，要学习的东西更多了。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp; 先总结到这里，如果大家有什么好的经验或建议，请多多提出，大家共同交流！</p>
<img src ="http://www.blogjava.net/junjie/aggbug/247317.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junjie/" target="_blank">wangjunjie</a> 2008-12-19 13:18 <a href="http://www.blogjava.net/junjie/archive/2008/12/19/247317.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SSH异常总结</title><link>http://www.blogjava.net/junjie/archive/2008/12/16/246643.html</link><dc:creator>wangjunjie</dc:creator><author>wangjunjie</author><pubDate>Tue, 16 Dec 2008 07:55:00 GMT</pubDate><guid>http://www.blogjava.net/junjie/archive/2008/12/16/246643.html</guid><wfw:comment>http://www.blogjava.net/junjie/comments/246643.html</wfw:comment><comments>http://www.blogjava.net/junjie/archive/2008/12/16/246643.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/junjie/comments/commentRss/246643.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/junjie/services/trackbacks/246643.html</trackback:ping><description><![CDATA[<p>1.HIBERNATE异常<br />
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is org.hibernate.InvalidMappingException: Could not parse mapping document from input stream<br />
Caused by: org.hibernate.InvalidMappingException: Could not parse mapping document from input stream<br />
&nbsp;at org.hibernate.cfg.Configuration.addInputStream(Configuration.java:508)<br />
&nbsp;at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:656)<br />
&nbsp;at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:134)<br />
&nbsp;at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1203)<br />
&nbsp;at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1172)<br />
&nbsp;at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:427)<br />
&nbsp;at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:249)<br />
&nbsp;at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:155)<br />
&nbsp;at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:246)<br />
&nbsp;at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:160)<br />
&nbsp;at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:285)<br />
&nbsp;at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:352)<br />
&nbsp;at org.springframework.context.support.ClassPathXmlApplicationContext.&lt;init&gt;(ClassPathXmlApplicationContext.java:122)<br />
&nbsp;at org.springframework.context.support.ClassPathXmlApplicationContext.&lt;init&gt;(ClassPathXmlApplicationContext.java:66)<br />
&nbsp;at cn.qdqn.ssh.test.AddUserInfo.main(AddUserInfo.java:25)<br />
Caused by: org.dom4j.DocumentException: \G1:\JAR\hibernate-mapping-3.0.dtd (文件名、目录名或卷标语法不正确。) Nested exception: \G1:\JAR\hibernate-mapping-3.0.dtd (文件名、目录名或卷标语法不正确。)<br />
&nbsp;at org.dom4j.io.SAXReader.read(SAXReader.java:484)<br />
&nbsp;at org.hibernate.cfg.Configuration.addInputStream(Configuration.java:499)<br />
&nbsp;... 14 more</p>
<p>异常类型：HiBERNATE中的xml解析器不能找到DTD文件 <br />
异常原因：因为hibernate的xml解析器解析.xml文件的时候需要根据文档头的 DOCTYPE去找DTD定义文件<br />
查看你定义的.xml文件是有效。<br />
解决方法：正确配置DTD文件的路径</p>
<img src ="http://www.blogjava.net/junjie/aggbug/246643.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/junjie/" target="_blank">wangjunjie</a> 2008-12-16 15:55 <a href="http://www.blogjava.net/junjie/archive/2008/12/16/246643.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>