<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>sunnylocus's blog</title>
    <description>希望一起交流技术，共同提高!我喜欢交朋友，有兴趣的朋友不防加我QQ 一起讨论下编程或工作遇到的难题。QQ：214899085</description>
    <link>http://sunnylocus.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
          <item>
        <title>static块的作用及何时被执行</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/233769" style="color:red;">http://sunnylocus.javaeye.com/blog/233769</a>&nbsp;
          发表时间: 2008年08月28日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="font-size: x-small; color: #000000;"> 在逛论坛的看到很多的朋友在讨论staic块，进去瞧瞧，感觉有点雾里看花。我也不知道static块到底有什么用，何时用。学习下吧，好象JDBC就用到这些东西。</span></p>
<p><span style="font-size: x-small; color: #000000;">&nbsp;&nbsp;&nbsp; 一般情况下,如果有些代码必须在项目启动的时候就要被执行,这种情况上就需要使用静态代码块,这种代码是主动执行的，写个例子看看static块什么时候被执行</span></p>
<p><span style="font-size: small; color: #3366ff;">1.StaticTest</span></p>
<pre name="code" class="java">package com.test.statictest;

public class StaticTest {
	/** 构造方法*/
	public StaticTest() {
		System.out.println("构造函数被执行了!");
	}
	/** 静态代码快*/
	static {
		System.out.println("静态代码块被执行了!");
		//show();
	}
	/** 静态方法*/
	public static void show(){
		System.out.println("静态方法被执行了!");
	}
}
</pre>
<p>&nbsp;</p>
<p><span style="font-size: small; color: #3366ff;">2.Main</span></p>
<pre name="code" class="java">package com.test.statictest;

public class Main {
	public static void main(String[] args) throws ClassNotFoundException {
		Main main = new Main();
		//加载类
		Class.forName("com.test.statictest.StaticTest");
		Class.forName("com.test.statictest.StaticTest");
		
	}
}</pre>
<p>&nbsp;结果输出</p>
<p>&nbsp;&nbsp;&nbsp; <span style="color: #993300;">静态代码块被执行了!</span></p>
<p><span style="font-size: small; color: #800000;">在测试类里我加载了2次StaticTest类，按理说"静态代码块被执行了!"这句话应执行二次,但只输出了一次。</span></p>
<p>&nbsp;</p>
<p><span style="font-size: small; color: #800000;">再看看别的</span></p>
<p><span style="font-size: small; color: #800000;">&nbsp;&nbsp;&nbsp;
<pre name="code" class="java">package com.test.statictest;

public class Main {
	public static void main(String[] args) throws ClassNotFoundException {
		Main main = new Main();
		//加载类
		Class.forName("com.test.statictest.StaticTest",true,Main.class.getClassLoader());
		//Class.forName("com.test.statictest.StaticTest");		
	}
}</pre>
<p>&nbsp;结果：</p>
<p>&nbsp;&nbsp;&nbsp; <span style="color: #993300;">静态代码块被执行了!</span></p>
<p><span style="color: #993300;">这两个语句是等价的，执行的结果相同。</span></p>
<p>&nbsp;</p>
<p><span style="color: #000000;">把<span style="font-size: x-small;">Class.forName("com.test.statictest.StaticTest",true,Main.class.getClassLoader())中的true改为false，代表加载类的时候不初始化静态代码块的内容，只能在这个类被实例化的时候才能初始化</span></span></p>
<p>&nbsp;</p>
<p><span style="color: #000000;">&nbsp;&nbsp; Class.<span class="undefined">forName</span>(xxx.xx.xx)的作用是要求JVM查找并加载指定的类，也就是说JVM会执行该类的静态代码块.</span></p>
<p><span style="color: #000000;">看看JDBC是怎么对Class.forName解释的:</span></p>
<p><span style="font-size: x-small;"><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; we just want to load the driver to jvm only, but not need to user the instance of driver, so call <span class="hilite1"><span style="color: #000000; background-color: #ffffff;">Class</span></span>.<span class="undefined">forName</span>(xxx.xx.xx) is enough, if you call <span class="hilite1"><span style="background-color: #ffffff;">Class</span></span>.<span class="undefined">forName</span>(xxx.xx.xx).newInstance(), the result will same as calling <span class="hilite1"><span style="background-color: #ffffff;">Class</span></span>.<span class="undefined">forName</span>(xxx.xx.xx), because <span class="hilite1"><span style="background-color: #ffffff;">Class</span></span>.<span class="undefined">forName</span>(xxx.xx.xx).newInstance() will load driver first, and then create instance, but the instacne you will never use in usual, so you need not to create it.</span> </span></p>
<p><span style="font-size: x-small;">翻译：</span></p>
<font size="3" color="#800000">
<p><span style="font-size: x-small;">&nbsp;&nbsp; <span style="color: #ff0000;">我们只是想加载这个驱动到JVM,并不需要实例化这个驱动，因此调用Class.forName(xxx.xxx.xx) 足够，如果你调用Class.forName(xxx.xxx.xxx).newInstance(),结果和调用Class.forName(xxx.xxx.xxx)是一样的，因为Class.forName(xxx.xxx.xxx).newInstance() 会首先加载驱动并创建实例，但是这个实例通常你决不会用到，所有你不需要创建它。</span></span></p>
</font></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/233769#comments" style="color:red;">已有 <strong>2</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 28 Aug 2008 10:56:42 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/233769</link>
        <guid>http://sunnylocus.javaeye.com/blog/233769</guid>
      </item>
          <item>
        <title>Java设计模式—观察者模式(Observer pattern)</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/233212" style="color:red;">http://sunnylocus.javaeye.com/blog/233212</a>&nbsp;
          发表时间: 2008年08月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="color: #3366ff; font-family: Courier New;"><span style="font-size: small;"><span style="color: #000000;">&nbsp;&nbsp; 观察者模式在软件编程中用的较多，我不善于表达我就用在网上看到的故事，和生活的例子说下基本思想</span>&nbsp;</span></span></p>
<p><span style="font-size: small; color: #3366ff; font-family: Courier New;">故事：</span></p>
<p><span style="font-size: small; color: #3366ff; font-family: Courier New;">&nbsp; &nbsp;小雪是一个非常漂亮的女孩，漂亮的女孩总是有很多的追求者，而且追求者的队伍在不断的变动，随时有人进入这个队伍，也有人退出。男孩们追求女孩时总是表现出120%的关心，当小雪私自游玩时总是不断收到追求者询问小雪位置变动的消息，小雪也不胜其烦，但小雪是如此的一个善良的女孩，她总是打断自己正常的生活回复男孩们的消息。而男孩们由于要不断的关心小雪的位置变化也弄的精疲力竭，而且还影响正常的工作。</span><span style="font-size: small; color: #3366ff; font-family: Courier New;">在这样一个简单的故事场景中我们发现了什么？来看看小雪和男孩们的烦恼： <br /></span><span style="font-size: small; color: #3366ff; font-family: Courier New;">&nbsp; 1.男孩们必须不断的询问小雪的位置变化，从而打断正常的工作;&nbsp;<br />&nbsp; 2.小雪也要不断的接受男孩们的询问，有的时候小雪的位置并没有发生变化，还是要不断的回复男孩们的询问，也影响正常的工作。</span></p>
<p><span style="font-size: small; color: #3366ff; font-family: Courier New;">&nbsp;&nbsp;3.如果给各个男孩们回复问题的方式都不尽相同，小雪还要知道不同的回复方式，而且不断的有新的男孩们增加进来，还不知道未来有什么新的回复方式。 </span></p>
<p><span style="font-family: Courier New;"><span style="font-size: small;"><span style="color: #3366ff;">&nbsp;&nbsp;&nbsp; 看到这么多烦恼，我们创意无限的Nokia公司给小雪和男孩们提出了解决方案： <br />&nbsp;&nbsp;&nbsp; Nokia公司荣誉出品了一款带有GPRS功能的手机，该手机保存着一个订阅位置变化短信通知的电话列表，当该手机检测到位置发生变化就会向这个订阅列表里的所有手机发送短信。看到Nokia这个解决方案，男孩们和小雪都应该松一口气，他们各自都可以按照自己正常的生活习惯，只有状态发生变化时候各自才会进行通信</span>。</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small; font-family: Courier New;">&nbsp;&nbsp; 观察者模式还可以用生活中一个例子来表达，就是从邮局订杂志。假如有一个叫 妮妮 的女孩在A邮局订了《时尚女孩》的杂志，又在B邮局订了《知音》杂志，并且告诉这两家邮局，如果杂志到了就给我打电话我自己来拿，然后邮局就在系统中注册下这个女孩姓名，电话等信息。妮妮剩下的就是等邮局的电话来取杂志了。如果杂志到了，邮局打电话给妮妮说,您的杂志到了，请到某某邮局来取（这相当于程序中把对象的引用&mdash;&mdash;邮局名，传给观察者），如果只说您的杂志到了，请到邮局来取，妮妮怎么知道去哪个邮局拿杂志呀。</span></p>
<p>&nbsp;</p>
<p><span style="font-size: small; font-family: Courier New;">下面的程序模仿上面的情形，一个随机数产生对象和两个观察者，这两个观察者都在随机数产生对象那里注册了，意思说如果你产生了新的数字，就通知我一声。</span></p>
<p>&nbsp;</p>
<p><span style="font-size: x-small; font-family: Courier New;">结构图:</span></p>
<p>
<table class="quote_title" border="1" align="center" width="558" style="height: 124px; style: boder;">
<caption>类说明</caption>
<tbody>
<tr>
<td>&nbsp;名称</td>
<td>&nbsp;功能说明</td>
</tr>
<tr>
<td>&nbsp;Observer</td>
<td>&nbsp;表示观察者的接口，要成为观察者必须实现此接口才行</td>
</tr>
<tr>
<td>&nbsp;NumberGenerator</td>
<td>&nbsp;表示产生数值的抽象类</td>
</tr>
<tr>
<td>&nbsp;RandomNumberGenerator</td>
<td>&nbsp;产生随机数的类，继承于NumberGenerator</td>
</tr>
<tr>
<td>&nbsp;NumberObserver</td>
<td>&nbsp;数字观察者，会打印出变化的数字</td>
</tr>
<tr>
<td>&nbsp;SymbolObserver</td>
<td>&nbsp;符号观察者,打印N 个符号,打印多少个符号，由接受到的数值确定</td>
</tr>
</tbody>
</table>
</p>
<p><img src="../../../upload/picture/pic/20675/ddc1cacf-b014-34fd-a6d6-d7a62471054c.jpg" height="422" alt="" width="746" /></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>1.Observer</p>
<pre name="code" class="java">package com.pattern.observer;

public interface Observer {
	public abstract void update(NumberGenerator generator);
}</pre>
<p>2.NumberGenerator</p>
<p>&nbsp; </p>
<pre name="code" class="java">package com.pattern.observer;

import java.util.ArrayList;
import java.util.Iterator;

/**
 * @project JavaPattern
 * @author sunnylocus	
 * @verson 1.0.0
 * @date   Aug 27, 2008 1:35:34 PM
 * @description 产生数值的抽象类
 */
public abstract class NumberGenerator {
	private ArrayList observers = new ArrayList();  //存储Observer
	/** 添加观察者*/
	public void addObserver(Observer observer) {
		observers.add(observer);
	}
	/** 删除观察者*/
	public void delObserver(Observer observer) {
		observers.remove(observer);
	}
	/** 通知所有观察者*/
	public void notifyObservers() {
		Iterator it = observers.iterator();
		while(it.hasNext()) {
			Observer o =(Observer) it.next();
			o.update(this);//this相当于上面提到的邮局名
		}
	}
	public abstract int getNumber();//获取数字
	public abstract void generate();//产生数字
}
</pre>
<p>&nbsp;</p>
<p>3.RandomNumberGenerator</p>
<pre name="code" class="java">package com.pattern.observer;

import java.util.Random;

/**
 * @project JavaPattern
 * @author sunnylocus	
 * @verson 1.0.0
 * @date   Aug 27, 2008 1:48:03 PM
 * @description 用于产生随机数及通知观察者的类
 */
public class RandomNumberGenerator extends NumberGenerator{
	private Random random = new Random();//随机数产生器
	private int number;   //用于存放数字

	public void generate() {
		for(int i=0 ; i &lt; 5; i++) {
			number = random.nextInt(10);//产生10以内的随机数
			notifyObservers();  //有新产生的数字，通知所有注册的观察者
		}
	}
    /** 获得数字*/
	public int getNumber() {
		return number;
	}
	
}
</pre>
<p>&nbsp;</p>
<p>4.NumberObserver</p>
<pre name="code" class="java">package com.pattern.observer;

/** 以数字表示观察者的类*/
public class NumberObserver implements Observer{
	public void update(NumberGenerator generator) {
		System.out.println("NumberObserver:"+ generator.getNumber());
		try {
			Thread.sleep(1000 * 3); //为了能清楚的看到输出，休眠3秒钟。
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
	}
	
}
</pre>
<p>&nbsp;</p>
<p>5.SymbolObserver</p>
<pre name="code" class="java">package com.pattern.observer;

/** 以符号表示观察者的类*/
public class SymbolObserver implements Observer{
	public void update(NumberGenerator generator) {
		System.out.print("SymbolObserver:");
		int count = generator.getNumber();
		
		for(int i = 0 ; i &lt; count; i ++) {
			System.out.print("*^_^*  ");
		}
		System.out.println("");
		try {
			Thread.sleep(1000 * 3);
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}
}
</pre>
<p>&nbsp;</p>
<p>6.Main(测试类)</p>
<pre name="code" class="java">package com.pattern.observer;

public class Main {
	public static void main(String[] args) {
		//实例化数字产生对象
		NumberGenerator generator = new RandomNumberGenerator();
		//实例化观察者
		Observer observer1 = new NumberObserver();
		Observer observer2 = new SymbolObserver();
		//注册观察者
		generator.addObserver(observer1);
		generator.addObserver(observer2);
		
		generator.generate(); //产生数字
	}
}
</pre>
<p>&nbsp;7.结果输出</p>
<p><img src="../../../upload/picture/pic/20677/ce27c300-99b6-3f9e-a738-c6b439a37c35.jpg" height="200" alt="" width="594" /></p>
<p>&nbsp;</p>
<p><span style="color: #ff0000;">设计思想：</span></p>
<p><span style="font-size: 10.5pt; mso-bidi-font-size: 12.0pt; mso-ascii-: 1.0pt;"><span style="color: #ff0000;">&nbsp;&nbsp;&nbsp;&nbsp; 观察者模式定义了对象之间的一对多的依赖关系，当一个对象的状态发生改变时，所有它的依赖对象将被自动通知并更新</span></span></p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/233212#comments" style="color:red;">已有 <strong>11</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 27 Aug 2008 15:23:19 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/233212</link>
        <guid>http://sunnylocus.javaeye.com/blog/233212</guid>
      </item>
          <item>
        <title>Java设计模式—工厂方法(Factory Method)</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/232915" style="color:red;">http://sunnylocus.javaeye.com/blog/232915</a>&nbsp;
          发表时间: 2008年08月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp; <span style="font-size: small;">Template Method Pattern是在父类建立处理逻辑的大纲骨架，而在子类补充具体的处理内容，如果把模板方法用在产生对象实例方面，就是式厂方法模式<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Factory Method Pattern在父类规定对象的创建方法，但并没有深入到较具体的类名。所有具体的完整内容都放在子类，根据这个原则，我们可以大致分成产生对象实例的框架和实际产生对象实例的类两方面</span></p>
<p><span style="font-size: small;">&nbsp;&nbsp;&nbsp;&nbsp;1.框架类</span></p>
<p><span style="font-size: small;">
<pre name="code" class="java">package com.pattern.factorymethod;

public abstract class Factory {
	public final Cup make(String shape,String color) {//产生对象的方法，用final修饰把保证在子类中不会被修改
		Cup cup = makeCup(shape);
		smearColor(cup,color);
		return cup;
	}
	protected abstract Cup makeCup(String shape); //抽象方法，制作水杯，shape参数指定水杯的外形
	protected abstract void smearColor(Cup cup,String color);  //抽象方法，给水杯涂上颜色
	
}
</pre>
<p>&nbsp;2.实现类</p>
<p>&nbsp;&nbsp; </p>
<pre name="code" class="java">package com.pattern.factorymethod;

public class CupFactory extends Factory {

	protected Cup makeCup(String shape) {
		Cup cup = new Cup();
		cup.setShape(shape);
		return cup;
	}
	protected void smearColor(Cup cup, String color) {//涂颜色
		cup.setColor(color);
	}

}</pre>
<p>&nbsp;3.水杯(实体类)</p>
<p>&nbsp;</p>
<pre name="code" class="java">package com.pattern.factorymethod;

public  class Cup {
	private String shape;
	private String color;

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

	public String getShape() {
		return shape;
	}

	public void setShape(String shape) {
		this.shape = shape;
	}	
	
}
</pre>
<p>&nbsp;</p>
<p>4.测试</p>
<p>&nbsp;</p>
<pre name="code" class="java">package com.pattern.factorymethod;

public class Main {
	public static void main(String[] args) {
		//创建一个水杯工厂
		CupFactory factory = new CupFactory();
		Cup cup1 = factory.make("圆形", "红色");//我要一个圆形，红色的杯子 
		System.out.println("杯子造好了");
		System.out.println("形状："+cup1.getShape());
		System.out.println("颜色："+cup1.getColor());
		
		Cup cup2 = factory.make("方形", "蓝色");//我要一个方形，蓝色的杯子 
		System.out.println("杯子造好了");
		System.out.println("形状："+cup2.getShape());
		System.out.println("颜色："+cup2.getColor());
	}
}</pre>
<p>&nbsp;</p>
<p>结果：</p>
<p>&nbsp;<span style="color: #0000ff;">&nbsp;&nbsp; </span><span style="color: #3366ff;">杯子造好了<br />&nbsp;&nbsp;&nbsp; 形状：圆形<br />&nbsp;&nbsp;&nbsp;&nbsp;颜色：红色<br />&nbsp;&nbsp;&nbsp; 杯子造好了<br />&nbsp;&nbsp;&nbsp; 形状：方形<br />&nbsp;&nbsp;&nbsp; 颜色：蓝色</span></p>
<font size="3">
<p>&nbsp; </p>
</font></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/232915#comments" style="color:red;">已有 <strong>2</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 26 Aug 2008 16:42:31 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/232915</link>
        <guid>http://sunnylocus.javaeye.com/blog/232915</guid>
      </item>
          <item>
        <title>Linux系统开机，tomcat自动启动</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/231243" style="color:red;">http://sunnylocus.javaeye.com/blog/231243</a>&nbsp;
          发表时间: 2008年08月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-size: small;">修改配置文件，使tomcat自动启动</span></p>
<p><span style="font-size: x-small; color: #ff0000;">(假设tomcat的安装路径位于 /opt/apache-tomcat5.5.26目录下)</span></p>
<ol>
<li><span style="font-size: small; color: #3366ff;">在root根目录下，输入 vi /etc/profile</span></li>
<li><span style="font-size: small; color: #3366ff;">在profile文件中加入下面几句话 </span></li>
<li><span style="font-size: small; color: #3366ff;">&nbsp;&nbsp; cd /opt/apache-tomcat5.5.26/bin</span></li>
<li><span style="font-size: small; color: #3366ff;">&nbsp;&nbsp;&nbsp;chmod 777 *&nbsp; //<span style="font-size: small; color: #3366ff;">&nbsp;把bin目录下的所有文件的权限设置最大，否则将不能运行</span></span></li>
<li><span style="font-size: small; color: #3366ff;">&nbsp;&nbsp;&nbsp;./startup.sh</span></li>
<li><span style="font-size: small; color: #3366ff;">保存退出</span></li>
</ol>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/231243#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 21 Aug 2008 16:42:10 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/231243</link>
        <guid>http://sunnylocus.javaeye.com/blog/231243</guid>
      </item>
          <item>
        <title>在Linux系统中设置Java环境变量</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/231222" style="color:red;">http://sunnylocus.javaeye.com/blog/231222</a>&nbsp;
          发表时间: 2008年08月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>1. 修改/etc/profile文件</p>
<p>　　　　如果你的计算机仅仅作为开发使用时推荐使用这种方法，因为所有用户的shell都有权使用这些环境变量，可能会给系统带来安全性问题。</p>
<p>　　　　&middot;用文本编辑器打开/etc/profile<br />　　　　&middot;在profile文件末尾加入：</p>
<p>　　　　　</p>
<pre name="code" class="java">　          JAVA_HOME=/usr/share/jdk1.5.0_05
　　　　　　PATH=$JAVA_HOME/bin:$PATH
　　        CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
　　　　　　export JAVA_HOME
　　　　　　export PATH
　　　　　　export CLASSPATH</pre>
<p>　　　　&middot;重新登录<br />　　　　&middot;提示 <br />　　　　　　CLASSPATH中的&ldquo;.&rdquo;不能丢！<br />　　　　</p>
<p>　　2. 修改.bashrc文件<br />　　　　这种方法更为安全，它可以把使用这些环境变量的权限控制到用户级别，如果你需要给某个用户权限使用这些环境变量，你只需要修改其个人用户主目录下的.bashrc文件就可以了。</p>
<p>　　　　&middot;用文本编辑器打开用户目录下的.bashrc文件<br />　　　　&middot;在.bashrc文件末尾加入：<br />　　　　</p>
<pre name="code" class="java">                  set JAVA_HOME=/usr/share/jdk1.5.0_05
　　　　　　export JAVA_HOME
　　　　　　set PATH=$JAVA_HOME/bin:$PATH
            　　export PATH
            　　set CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
            　　export CLASSPATH</pre>
<p>　　　　&middot;重新登录</p>
<p>&nbsp;</p>
<p>　　3. 直接在shell下设置变量</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一次性设置，因为换个shell 你的设置就失效了.</p>
<p>　　　　只需在shell终端执行下列命令：</p>
<p>　　　　</p>
<pre name="code" class="java">            export JAVA_HOME=/usr/share/jdk1.5.0_05
　　　　export PATH=$JAVA_HOME/bin:$PATH
　　　　export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar</pre>
<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/231222#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 21 Aug 2008 16:03:56 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/231222</link>
        <guid>http://sunnylocus.javaeye.com/blog/231222</guid>
      </item>
          <item>
        <title>Linux登陆密码遗忘解决办法</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/231208" style="color:red;">http://sunnylocus.javaeye.com/blog/231208</a>&nbsp;
          发表时间: 2008年08月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-size: small; font-family: 宋体;">管理员密码修改过程：</span></p>
<ol>
<li><span style="font-size: small; color: #ff0000;">&nbsp;&nbsp; 启动Linux系统</span></li>
<li><span style="font-size: small; color: #ff0000;">&nbsp;&nbsp; 出现蓝色的Grub界面</span></li>
<li><span style="font-size: small; color: #ff0000;">&nbsp;&nbsp; 选择Red Hat操作系统</span></li>
<li><span style="font-size: small; color: #ff0000;">&nbsp;&nbsp; 按e</span></li>
<li><span style="font-size: small; color: #ff0000;">&nbsp;&nbsp; 选择第二行,按e</span></li>
<li><span style="font-size: small; color: #ff0000;">&nbsp;&nbsp; 在行尾加上 1或s ,回车</span></li>
<li><span style="font-size: small; color: #ff0000;">&nbsp;&nbsp; 按b启动</span></li>
<li><span style="font-size: small; color: #ff0000;">&nbsp;&nbsp; 在提示符后面输入 passwd root</span></li>
<li><span style="font-size: small; color: #ff0000;">&nbsp;&nbsp; 输入两次一样的新密码</span></li>
<li><span style="font-size: small; color: #ff0000;">&nbsp;&nbsp; init 3 或init 5</span></li>
</ol>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/231208#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 21 Aug 2008 15:42:30 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/231208</link>
        <guid>http://sunnylocus.javaeye.com/blog/231208</guid>
      </item>
          <item>
        <title>Java密码加密</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/228630" style="color:red;">http://sunnylocus.javaeye.com/blog/228630</a>&nbsp;
          发表时间: 2008年08月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">package com.sunnylocus.util;

import java.security.MessageDigest;

/** 
 * 对密码进行加密和验证的类
 */
public class CipherUtil{
    
    //十六进制下数字到字符的映射数组
    private final static String[] hexDigits = {"0", "1", "2", "3", "4",
        "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
    
    /** * 把inputString加密     */
    public static String generatePassword(String inputString){
        return encodeByMD5(inputString);
    }
    
      /**
       * 验证输入的密码是否正确
     * @param password    加密后的密码
     * @param inputString    输入的字符串
     * @return    验证结果，TRUE:正确 FALSE:错误
     */
    public static boolean validatePassword(String password, String inputString){
        if(password.equals(encodeByMD5(inputString))){
            return true;
        } else{
            return false;
        }
    }
    /**  对字符串进行MD5加密     */
    private static String encodeByMD5(String originString){
        if (originString != null){
            try{
                //创建具有指定算法名称的信息摘要
                MessageDigest md = MessageDigest.getInstance("MD5");
                //使用指定的字节数组对摘要进行最后更新，然后完成摘要计算
                byte[] results = md.digest(originString.getBytes());
                //将得到的字节数组变成字符串返回
                String resultString = byteArrayToHexString(results);
                return resultString.toUpperCase();
            } catch(Exception ex){
                ex.printStackTrace();
            }
        }
        return null;
    }
    
    /** 
     * 转换字节数组为十六进制字符串
     * @param     字节数组
     * @return    十六进制字符串
     */
    private static String byteArrayToHexString(byte[] b){
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i &lt; b.length; i++){
            resultSb.append(byteToHexString(b[i]));
        }
        return resultSb.toString();
    }
    
    /** 将一个字节转化成十六进制形式的字符串     */
    private static String byteToHexString(byte b){
        int n = b;
        if (n &lt; 0)
            n = 256 + n;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }
}</pre>
<p>&nbsp;</p>
<pre name="code" class="java">package com.sunnylocus.util;

public class Main {
	public static void main(String[] args) {
		String pwd1="123";
		String pwd2="";
		CipherUtil cipher = new CipherUtil();
		System.out.println("未加密的密码:"+pwd1);
		//将123加密
		pwd2 = cipher.generatePassword(pwd1);
		System.out.println("加密后的密码:"+pwd2);
		
		System.out.print("验证密码是否下确:");
		if(cipher.validatePassword(pwd2, pwd1)) {
			System.out.println("正确");
		}
		else {
			System.out.println("错误");
		}
	}
}
</pre>
<p>&nbsp;</p>
<p>结果输出：</p>
<pre name="code" class="java">未加密的密码:123
加密后的密码:202CB962AC59075B964B07152D234B70
验证密码是否下确:正确</pre>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/228630#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 16 Aug 2008 12:16:35 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/228630</link>
        <guid>http://sunnylocus.javaeye.com/blog/228630</guid>
      </item>
          <item>
        <title>Java设计模式—单态模式(Singleton)</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/228419" style="color:red;">http://sunnylocus.javaeye.com/blog/228419</a>&nbsp;
          发表时间: 2008年08月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-size: small;">&nbsp; 单态模式(也有叫单例模式)表示一个类只有一个实例存在，生成用单态模式设计类不能用new 关键字来获得。可用简单的一句话来概括单态模式：</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size: small; color: #ff0000;">构造方法私有化，通过共有的静态方法返回类的实例。</span></p>
<p><span style="font-size: small; color: #000000;">&nbsp;&nbsp;&nbsp; 最近在项目开发中，程序用到的各个参数被单独拿出来做成一个配置文件，程序接收到用户的定位请求就从配置文件读取出对应的参数和客户端中请求的参数比对，然后把定位请求发送到不同的定位平台，但问题来了，每次读取文件就要new 一个文件对象，而定位请求每秒可能有几个至几十个，频繁的文件读取导致服务器性能下降(读取文件，要生成文件对象，打开文件流，读取，关闭文件流)。就种情况就要用到单态模式，程序一启动就生成唯一的一个文件对象，这样每次读取文件不再与文件物理的建立I/O流，直接从内存中读取即可。</span></p>
<p><span style="font-size: small;">1.单态类</span></p>
<pre name="code" class="java">package com.sunnylocus.singleton;

import java.io.File;

public class Singleton {
	private static Singleton instance;
	private static File configFile;
	private Singleton() { //构造方法私有化
	}
	/** 获得配置文件对象*/
	public File getConfigFile() {
		return configFile;
	}
	/** 获得Singleton类的实例*/
	public static Singleton getInstance() {//通过公有的静态方法返回类的实例
		if(instance == null) {
			configFile = new File("src/com/sunnylocus/singleton/locationConfig.xml"); 
			instance = new Singleton();
		}
		
		return instance;
	}
}
</pre>
<p>&nbsp;</p>
<p><span style="font-size: small;">2.Test</span></p>
<pre name="code" class="java">package com.sunnylocus.singleton;

import java.io.File;

public class Main {
	public static void main(String[] args) {
		Singleton s1 = Singleton.getInstance();
		Singleton s2 = Singleton.getInstance();
		
		if(s1 == s2) { //比较地址
			System.out.println("s1和s2是同一个对象的实例");
		}
		else {
			System.out.println("s1和s2不是同一个对象的实例");
		}
		
		File f1 = s1.getConfigFile();
		File f2 = s1.getConfigFile();
		if(f1 == f2) {
			System.out.println("来自同一个文件对象");
		}
		else {
			System.out.println("不是来自同一个文件对象");
		}
	}
}
</pre>
<p>&nbsp;</p>
<p><span style="font-size: small;">3.output:</span></p>
<p><span style="font-size: small;">&nbsp;
<pre name="code" class="java">s1和s2是同一个对象的实例
来自同一个文件对象</pre>
<font size="3">
<p>&nbsp;</p>
</font></span></p>
<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/228419#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 15 Aug 2008 15:53:02 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/228419</link>
        <guid>http://sunnylocus.javaeye.com/blog/228419</guid>
      </item>
          <item>
        <title>创建Java线程池</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/223327" style="color:red;">http://sunnylocus.javaeye.com/blog/223327</a>&nbsp;
          发表时间: 2008年08月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-size: x-small; color: #800000;">线程池的作用:</span></p>
<p><span style="font-size: x-small; color: #800000;">&nbsp;&nbsp;&nbsp;&nbsp; 线程池作用就是限制系统中执行线程的数量。<br />&nbsp;&nbsp;&nbsp;&nbsp; 根据系统的环境情况，可以自动或手动设置线程数量，达到运行的最佳效果；少了浪费了系统资源，多了造成系统拥挤效率不高。用线程池控制线程数量，其他线程排队等候。一个任务执行完毕，再从队列的中取最前面的任务开始执行。若队列中没有等待进程，线程池的这一资源处于等待。当一个新任务需要运行时，如果线程池中有等待的工作线程，就可以开始运行了；否则进入等待队列。</span></p>
<p>&nbsp;</p>
<p><span style="font-size: x-small; color: #800000;">为什么要用线程池:</span></p>
<ol>
<li><span style="font-size: x-small; color: #800000;">减少了创建和销毁线程的次数，每个工作线程都可以被重复利用，可执行多个任务</span></li>
<li><span style="font-size: x-small; color: #800000;">可以根据系统的承受能力，调整线程池中工作线线程的数目，防止因为因为消耗过多的内存，而把服务器累趴下(每个线程需要大约1MB内存，线程开的越多，消耗的内存也就越大，最后死机)</span></li>
</ol>
<p><span style="font-size: x-small; color: #800000;">线程池类</span></p>
<p><span style="font-size: x-small; color: #800000;">&nbsp;&nbsp;&nbsp;&nbsp;
<pre name="code" class="java">package com.tdt.impl.ls;

import java.util.LinkedList;

/**
 * @project LocationGateway
 * @author sunnylocus	
 * @verson 1.0.0
 * @date   Aug 2, 2008
 * @jdk    1.4.2
 */
public class ThreadPool extends ThreadGroup {
	private boolean isClosed = false;  //线程池是否关闭 
	private LinkedList workQueue;      //工作队列
	private static int threadPoolID = 1;  //线程池的id
	public ThreadPool(int poolSize) {  //poolSize 表示线程池中的工作线程的数量

		super(threadPoolID + "");      //指定ThreadGroup的名称
		setDaemon(true);               //继承到的方法，设置是否守护线程池
		workQueue = new LinkedList();  //创建工作队列
		for(int i = 0; i &lt; poolSize; i++) {
			new WorkThread(i).start();   //创建并启动工作线程,线程池数量是多少就创建多少个工作线程
		}
	}
	
	/** 向工作队列中加入一个新任务,由工作线程去执行该任务*/
	public synchronized void execute(Runnable task) {
		if(isClosed) {
			throw new IllegalStateException();
		}
		if(task != null) {
			workQueue.add(task);//向队列中加入一个任务
			notify(); 			//唤醒一个正在getTask()方法中待任务的工作线程
		}
	}
	
	/** 从工作队列中取出一个任务,工作线程会调用此方法*/
	private synchronized Runnable getTask(int threadid) throws InterruptedException {
		while(workQueue.size() == 0) {
			if(isClosed) return null;
			System.out.println("工作线程"+threadid+"等待任务...");
			wait();				//如果工作队列中没有任务,就等待任务
		}
		System.out.println("工作线程"+threadid+"开始执行任务...");
		return (Runnable) workQueue.removeFirst(); //反回队列中第一个元素,并从队列中删除
	}
	
	/** 关闭线程池 */
	public synchronized void closePool() {
		if(! isClosed) {
			waitFinish();        //等待工作线程执行完毕
			isClosed = true;
			workQueue.clear();  //清空工作队列
			interrupt(); 		//中断线程池中的所有的工作线程,此方法继承自ThreadGroup类
		}
	}
	
	/** 等待工作线程把所有任务执行完毕*/
	public void waitFinish() {
		synchronized (this) {
			isClosed = true;
			notifyAll();			//唤醒所有还在getTask()方法中等待任务的工作线程
		}
		Thread[] threads = new Thread[activeCount()]; //activeCount() 返回该线程组中活动线程的估计值。
		int count = enumerate(threads); //enumerate()方法继承自ThreadGroup类，根据活动线程的估计值获得线程组中当前所有活动的工作线程
		for(int i =0; i &lt; count; i++) { //等待所有工作线程结束
			try {
				threads[i].join();	//等待工作线程结束
			}catch(InterruptedException ex) {
				ex.printStackTrace();
			}
		}
	}

	/**
	 * 内部类,工作线程,负责从工作队列中取出任务,并执行
	 * @author sunnylocus
	 */
	private class WorkThread extends Thread {
		private int id;
		public WorkThread(int id) {
			//父类构造方法,将线程加入到当前ThreadPool线程组中
			super(ThreadPool.this,id+"");
			this.id =id;
		}
		public void run() {
			while(! isInterrupted()) {  //isInterrupted()方法继承自Thread类，判断线程是否被中断
				Runnable task = null;
				try {
					task = getTask(id);		//取出任务
				}catch(InterruptedException ex) {
					ex.printStackTrace();
				}
				//如果getTask()返回null或者线程执行getTask()时被中断，则结束此线程
				if(task == null) return;
				
				try {
					task.run();  //运行任务
				}catch(Throwable t) {
					t.printStackTrace();
				}
			}//  end while
		}//  end run
	}// end workThread
}</pre>
<p>&nbsp;</p>
<p>2.测试类</p>
<p>&nbsp;&nbsp; </p>
<pre name="code" class="java">package com.tdt.test;

import com.tdt.impl.ls.ThreadPool;

public class ThreadPoolTest {
	
	public static void main(String[] args) throws InterruptedException {
		ThreadPool threadPool = new ThreadPool(3); //创建一个有个3工作线程的线程池
		Thread.sleep(500); //休眠500毫秒,以便让线程池中的工作线程全部运行
		//运行任务
		for (int i = 0; i &lt;=5 ; i++) { //创建6个任务
			threadPool.execute(createTask(i));
		}
		threadPool.waitFinish(); //等待所有任务执行完毕
		threadPool.closePool(); //关闭线程池

	}

	private static Runnable createTask(final int taskID) {
		return new Runnable() {
			public void run() {
			//	System.out.println("Task" + taskID + "开始");
				System.out.println("Hello world");
			//	System.out.println("Task" + taskID + "结束");
			}
		};
	}
}
</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>结果:</p>
<pre name="code" class="java">工作线程0等待任务...
工作线程1等待任务...
工作线程2等待任务...

工作线程0开始执行任务...
Hello world
工作线程0等待任务...

工作线程1开始执行任务...
Hello world
工作线程1等待任务...

工作线程2开始执行任务...
Hello world
工作线程2等待任务...

工作线程0开始执行任务...
Hello world
工作线程0等待任务...

工作线程1开始执行任务...
Hello world
工作线程1等待任务...

工作线程2开始执行任务...
Hello world
工作线程2等待任务...</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
</span></p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/223327#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 02 Aug 2008 13:39:15 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/223327</link>
        <guid>http://sunnylocus.javaeye.com/blog/223327</guid>
      </item>
          <item>
        <title>synchronized方法验证,不要被谬论迷惑</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/222725" style="color:red;">http://sunnylocus.javaeye.com/blog/222725</a>&nbsp;
          发表时间: 2008年08月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-size: x-small;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size: small; color: #993300;">以前编程没有怎么接触过synchronized方法，不太了解，今天编程遇到了多个线程访问同一个共享资源的问题，google了下synchronized使用方法，网上有二种说法，第一种说法是当一个线程访问了某个对象中的synchronzied方法,其它线程可以继续访问其它的synchronized方法,第二个说法与第一种说法相反，不能访问。搞的我也不确定，更要命的是，这两种说法在网上一边又一边的转载，以讹传讹，要误导不少java新手。到底那一个是正确的，编个程序验证就清楚了</span></span><span style="color: #993300;"><span style="font-size: small;">。</span> </span><br /><br /><span style="font-size: x-small;">&nbsp;&nbsp; 下面是一个示例程序，有三个角色,一个家庭中的父亲，母亲，和儿子,同时在ATM取款机上向同一个银行账号进行取钱和查询的操作</span> <br /><span style="font-size: x-small;">1.银行类</span></p>
<p><span style="font-size: x-small;">&nbsp;&nbsp;
<pre name="code" class="java">package com.sunnylocus.test;

public class Bank  {
	private int money = 100;
	//取钱
	public synchronized void takeMoney(int num) {
			Thread.sleep(1000 * 5);   //取钱需要5秒
			money -= num;
	}
	//存钱
	public synchronized void addMoney(int num) {
			Thread.sleep(1000 * 10); //存钱需要10秒
			money += money;
	}
	//查询
	public int queryMoney() {
		return money;
	}
}</pre>
<font size="2">
<p>&nbsp;</p>
</font></span></p>
<p><br />2.<span style="font-size: x-small;">父亲类</span></p>
<pre name="code" class="java">package com.sunnylocus.test;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Father extends Thread{
	private Bank bank;
	private int num;
	
	DateFormat dateFormate = new SimpleDateFormat("a h:mm:ss");  //日期格式对象
	
	public Father(Bank bank,int num) {
		this.bank = bank;
		this.num = num;
	}

	public void run() {
		System.out.println("老爸正在取钱...      --"+dateFormate.format(new Date()));
		bank.takeMoney(num);
		System.out.println("老爸取走了"+num +"         --"+dateFormate.format(new Date()));
	}
	
}
</pre>
<p><br /><br />3.母亲类</p>
<pre name="code" class="java">package com.sunnylocus.test;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Monther extends Thread{
	private Bank bank;
	private int num;
	DateFormat dateFormate = new SimpleDateFormat("a h:mm:ss");  //日期格式对象
	
	public Monther(Bank bank,int num) {
		this.bank = bank;
		this.num = num;
	}

	public void run() {
		System.out.println("老妈正在取钱....         "+dateFormate.format(new Date()));
		bank.takeMoney(num);
		System.out.println("老妈取走了"+num+"         --"+dateFormate.format(new Date()));
	}
	
}
</pre>
<p><br /><br />4.儿子类</p>
<pre name="code" class="java">package com.sunnylocus.test;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Sun extends Thread{
	private Bank bank;
	DateFormat dateFormate = new SimpleDateFormat("a h:mm:ss");  //日期格式对象
	public Sun(Bank bank) {
		this.bank = bank;
	}

	public void run() {
		//查询余款
		System.out.println("儿子查询余额:"+bank.queryMoney() +"     --"+dateFormate.format(new Date()));
	}
}
</pre>
<p><br /><br />5.测试类</p>
<pre name="code" class="java">package com.sunnylocus.test;

public class Main {
	public static void main(String[] args) {
		//银行
		Bank bank = new Bank();
		//老爸
		Father father = new Father(bank,50);
		//老妈
		Monther monther = new Monther(bank,100);
		//儿子
		Sun sun = new Sun(bank);
		
		new Thread(father).start();
		new Thread(monther).start();
		new Thread(sun).start();
		
	}
}
</pre>
<p><br />输出结果:</p>
<pre name="code" class="java">老爸正在取钱...               --上午 11:52:01
老妈正在取钱....              --上午 11:52:01
儿子查询余额:100           --上午 11:52:01

老爸取走了50                 --上午 11:52:06
老妈取了30                    --上午 11:52:11</pre>
<p><br />&nbsp;&nbsp; <span style="font-size: small; color: #3366ff;">一共有三个线程，同时启动，父亲线程和母亲线程同时取款的操作，因为父亲线程已经占用了对象锁，所以母亲线程只能等到父亲执行完方法释放锁后，才能执行。即便父亲线程占用了对象锁，儿子线程也能调用非synchronzied方法<br />&nbsp;</span></p>
<p><span style="font-size: small; color: #3366ff;">&nbsp;&nbsp;&nbsp;&nbsp; 我们把母亲类的取钱的方法改成存钱的操作，虽然不是同一个synchronized方法.也一样不能执行，必须等到父亲线程方法执行完毕后，才能进行存钱的操作</span><br /><br /><span style="color: #0000ff;"><span style="font-size: x-small;">我的结论:&nbsp;<br /><span>&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size: small;"><span style="color: #ff0000;">s</span><span style="color: #ff0000;">ynchronized method(){}可以防止多个线程同时访问这个对象的synchronized方法,如果一个对象有多个synchronized方法，只要一个线 程访问了其中的一个synchronized方法，那么其它线程不能同时访问这个对象中的任何一个synchronized方法,但可以访问这个对象中的非synchronized方法。</span></span></span></span></span><span style="color: #ff0000;"> <br /></span></p>
<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/222725#comments" style="color:red;">已有 <strong>3</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 01 Aug 2008 13:19:32 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/222725</link>
        <guid>http://sunnylocus.javaeye.com/blog/222725</guid>
      </item>
          <item>
        <title>公司面试操作题—用webservice实现两个整数求和</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/216994" style="color:red;">http://sunnylocus.javaeye.com/blog/216994</a>&nbsp;
          发表时间: 2008年07月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-size: small;">&nbsp;&nbsp;&nbsp;&nbsp; 刚开始找工作那段时间，每天要面试好几家单位，不停的重复着面试,机试。有几家感觉希望挺大的,但最后也没有接到通知。我想可能是我没有工作经验，公司不信任吧。后来来到我现在这个公司，感觉这家公司很务实，面试主管只说，我们公司注重能力，能力高于学历。给了我三道题目,前两道不难,第一个题目是结合Oracle数据库建立一个登陆信息表,实现ajax登陆验证功能,第二个题目是用oracle语句实现jsp分页功能。前两道题目很简单，关键是第三道题目，用webservice实现两个整数求和,看到这个题目我连webservice的基本概念都不知道，回校问老师，老师也不清楚。没办法只能上网查资料，弄到半夜十二点半终于搞明白了。</span></p>
<p><span style="font-size: small;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 第二天机试顺利通过。之后公司来了几位应试的最后都被webService拒之门外，我问道怎么不上网查资料呢，他说，查了，网上的例子放到自己的机器出些不知道的错误，网上文章也都是些难懂的字眼看不懂。所以我把机试题的经验写到博客里，希望能对求职的朋友有一点帮助。</span></p>
<p><span style="color: #3366ff;">&nbsp;概念：</span></p>
<p>&nbsp;&nbsp;&nbsp; <span style="color: #3366ff;">Web Service主要是为了使原来各孤立的站点之间的信息能够相互通信、共享而提出的一种接口。 Web Service所使用的是Internet上统一、开放的标准，如HTTP、XML、SOAP（简单对象访问协议）、WSDL等，所以Web Service可以在任何支持这些标准的环境（Windows,Linux）中使用。注：SOAP协议（Simple Object Access Protocal,简单对象访问协议）,它是一个用于分散和分布式环境下网络信息交换的基于XML的通讯协议。在此协议下，软件组件或应用程序能够通过标准的HTTP协议进行通讯。它的设计目标就是简单性和扩展性，这有助于大量异构程序和平台之间的互操作性，从而使存在的应用程序能够被广泛的用户访问</span></p>
<p>&nbsp;</p>
<p><span style="font-size: small; color: #000000;">&nbsp;&nbsp;&nbsp; 说的通俗一点webservice它就是一个函数或着方法，它的特别之处在于这个方法布署到web容器之后，无论身处何地，只要能访问到这个web容器,谁都可以调用这个方法。实现webservie最快捷的就是用axis框架,将axis的几个jar包导入到项目里，把要实现webservice功能的类,复制一份放到WEBROOT目录下，将复制到WEBROOT目录下的类的后缀名改为.jws，然后布署到web容器，在地址栏中输入<a href="http://ip/">http://ip/</a>项目名/类文件.jws，将会看到如图所示的界面:</span></p>
<p><img src="../../../upload/picture/pic/18316/06a3329b-ea24-36c3-9964-b1894c0eddec.bmp" height="232" alt="" style="vertical-align: middle;" width="714" /></p>
<p>&nbsp;</p>
<p>&nbsp;<span style="font-size: small;">点击 <span style="color: #ff0000;">Click to see the WSDL</span> 会打开一个网页，网页包含一些xml的描述信息,如图</span></p>
<p><img src="../../../upload/picture/pic/18318/db359b82-339a-3e0e-a915-17c4c25c7d57.bmp" height="671" alt="" style="vertical-align: middle;" width="637" /></p>
<p><span style="font-size: small;">&nbsp;如果看到上面的信息，表明的你的webservice已经发布成功了，在程序里可以调用这个"函数"了</span></p>
<p><span style="font-size: small;">简单的webservice服务调用代码:</span></p>
<pre name="code" class="java">package com.sunnylocus.test;

import javax.xml.namespace.QName;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;

public class TestCalculate {

	public static void main(String[] args) {
		try {
			/*我在公司的服务器测试的,公司的tomcat已把端口改成80 所以ip地址后面不用加端口号*/
			String endpoint = "http://192.168.0.16/axis/Calculate.jws";
			Service service = new Service();
			Call call = null;
			call = (Call) service.createCall();
			//设置操作名称(或着说被调用的方法名)
			call.setOperationName(new QName(endpoint, "getSum"));
			//设置目标终端地址
			call.setTargetEndpointAddress(new java.net.URL(endpoint));
			//设置传入参数
			Object[] params = {new Integer(5),new Integer(3)};
			//调用webservice
			Integer sum = (Integer) call.invoke(params);
			System.out.println("两数之和:"+sum);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
}
</pre>
<p>&nbsp;</p>
<p><span style="color: #0000ff;">输出:</span></p>
<div class="quote_div"><span style="color: #0000ff;">两数之和:8</span></div>
<p>&nbsp;<span style="font-size: small;">代码及axis相关的jar包，我打包放在附件了，希望对找工作的朋友有点帮助。</span></p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/216994#comments" style="color:red;">已有 <strong>5</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 21 Jul 2008 16:01:27 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/216994</link>
        <guid>http://sunnylocus.javaeye.com/blog/216994</guid>
      </item>
          <item>
        <title>Java设计模式—模板方法(Template Method)</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/216500" style="color:red;">http://sunnylocus.javaeye.com/blog/216500</a>&nbsp;
          发表时间: 2008年07月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<span style="font-size: small;">模板是指在薄片塑料板上面写字后挖空,再使用毛笔或色笔涂满挖空部分,就能看到纯手工而以不失工整的字样,看到模板上的挖空形状,马上就知道最后会变出什么样子的字,不过实际上所显现出来的字样还是要依所使用的画笔种类而定.拿黑色签字笔当画笔,结果当然就是签字笔的字样;当用铅笔来画,得到的也只会是灰黑色的铅笔字;如果用五颜六色的彩色笔,自然能创出让人眼花的多色字.但是,无论使用哪种文具,制作出来的字样都还是脱不了模板上已经固定的形状。</span></p>
<p><span style="font-size: small;">&nbsp;&nbsp; 下面我们用例子说明模板方法</span></p>
<p><span style="font-size: small;">&nbsp; <span style="color: #3366ff;">程序示例类之间的关系</span></span></p>
<p><img src="../../../upload/picture/pic/18204/16db3b14-d1b7-3b6b-a078-90bc31b34e83.bmp" height="367" alt="" style="vertical-align: middle;" width="417" /></p>
<p><span style="font-size: small;">&nbsp; <span style="color: #0000ff;">1.模板类，相当于我们上面提到的薄片塑料板</span></span></p>
<pre name="code" class="java">package com.pattern.templateMethod;

/**
 * 抽象类,充当模板角色
 * @author administrator
 *
 */
public abstract class AbstractDisplay {
	//由子类实现的抽象方法
	public abstract void open();   
	public abstract void print();
	public abstract void close();
	//抽象类实现的方法,final可以保证在子类不会被修改
	public final void display() {
		open();   //先open...
		for(int i=0; i &lt; 5; i++) {  //反复输出5次
			print();  
		}
		close(); //输出完毕,close
	}
}
</pre>
<p>&nbsp;</p>
<p>&nbsp; <span style="font-size: small; color: #0000ff;">2.字符类，输出单个字符</span></p>
<pre name="code" class="java">package com.pattern.templateMethod;

public class CharDisplay extends AbstractDisplay {
	private char ch;     //应输出的字符
	public CharDisplay(char ch) {  //把构造函数传递过来的字符ch,存储在字段内
		this.ch = ch;
	}
  
	public void open() {
		System.out.print("&lt;&lt;");   //输出"&lt;&lt;"作为开始字符串
	}
	public void close() {
		System.out.println("&gt;&gt;");  //输出 "&gt;&gt;"作为结束字符串
	}
	public void print() {
		System.out.print(ch);    //输出存储在字段的字符
	}

}
</pre>
<p>&nbsp;</p>
<p>&nbsp;&nbsp; <span style="font-size: small; color: #0000ff;">3.字符串类，输出字符串</span></p>
<pre name="code" class="java">package com.pattern.templateMethod;

/**
 * 
 * @author administrator
 */
public class StringDisplay extends AbstractDisplay {
	private String string;  //应输出的字符串
	private int width;      //以byte为单位所求出的字符串的"长度"
	
	public StringDisplay(String string) {
		this.string =string;
		width = string.getBytes().length;
	}

	public void open() {  //打印头装饰字符串
		printLine();
	}
	public void print() { //打印内容
		System.out.println("|"+string+"|");
	}
	public void close() { //打印尾装饰字符串
		printLine();
	}

	public void printLine() {
		System.out.print("+");  //输出"+"号表示边框位置
		for(int i=0; i &lt; width; ++i) {
			System.out.print("-");  //当作线段
		}
		System.out.println("+");  //输出"+"号表示边框位置
	}
}
</pre>
<p>&nbsp;<span style="font-size: small; color: #0000ff;"> 4.测试类</span></p>
<pre name="code" class="java">package com.pattern.templateMethod;

public class Main {
	public static void main(String[] args) {
		//建立1个有'A'的CharDisplay的对象
		AbstractDisplay d1 = new CharDisplay('A');
		//建立1个有"Hello world"的StringDisplay的对象
		AbstractDisplay d2 = new StringDisplay("Hello World");
		
		//d1,d2都是AbstractDisplay的子类对象,可以调用继承到的display()方法
		d1.display();
		d2.display();
	}
}
</pre>
<p>&nbsp;</p>
<p>&nbsp;输出:</p>
<p><span style="font-size: small; color: #00ccff;"><span style="color: #3366ff;">&nbsp;
<pre name="code" class="c"> &lt;&lt;AAAAA&gt;&gt;
+-----------+
|Hello World|
|Hello World|
|Hello World|
|Hello World|
|Hello World|
+-----------+</pre>
<font size="3" color="#00ccff"><font color="#3366ff">
<p>&nbsp;</p>
</font></font></span><font size="3" color="#00ccff">
<p>&nbsp;</p>
</font></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-size: small; color: #3366ff;">设计思想：</span></p>
<p><span style="font-size: small; color: #3366ff;">&nbsp; <span style="color: #ff0000;">作为模板的方法定义在父类（父类为抽象类），而方法定义使用抽象方法，实现抽象方法的是子类，要在子类实现方法，才能决定具体的操作。如果在不同的子类执行不同实现就可以发展出不同的处理内容。不过，无论在哪个子类执行任何一种实现，处理的大致流程都还是要依照父类制定的方式。</span></span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/216500#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 19 Jul 2008 14:19:01 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/216500</link>
        <guid>http://sunnylocus.javaeye.com/blog/216500</guid>
      </item>
          <item>
        <title>Java设计模式—适配器(Adapter)</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/216150" style="color:red;">http://sunnylocus.javaeye.com/blog/216150</a>&nbsp;
          发表时间: 2008年07月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-size: small;">&nbsp; 如果现在有一台使用12V直流电的笔记本电脑，要将插头接到220V的交流电电源，直接接到电源我想笔记本要报销了。你需要用到一个交流电适配器(AC Adapter)。交流电适配器能够将家用的220V交流电转换成我们需要的12V直流电。适配器的功能就是介入原有电源和需要的电源之间，作为沟通的桥梁。适配器的原文是adapter,代表"适合"的意思。</span></p>
<p><span style="font-size: small;">&nbsp;&nbsp;&nbsp;&nbsp; 在程序设计中我们也需要用到&ldquo;适配器&rdquo;,如果原有的内容无法直接利用时，通常要转换成必要的类型后再使用，实现转换功能的就是</span></p>
<p><span style="font-size: small;">Adapter Pattern</span></p>
<p>&nbsp;</p>
<p><span style="font-size: small;">&nbsp;&nbsp;&nbsp; Adapter Pattern分为两种情况:</span></p>
<ul>
<li><span style="font-size: small;">&nbsp;&nbsp;&nbsp; 类的Adapter Pattern(继承)</span></li>
<li><span style="font-size: small;">&nbsp;&nbsp;&nbsp; 对象的Adapter Pattern(委托)</span></li>
</ul>
<p><span style="font-size: small;">下面的程序使用类的Adapter Pattern输出字符串"$Hello$"和"*Hello*"</span></p>
<p>&nbsp;<span style="font-size: small; color: #0000ff;">程序示例1</span></p>
<p><span style="font-size: small; color: #0000ff;">&nbsp; 1.Print接口，可以看成我们需要的内容</span></p>
<pre name="code" class="java">package com.pattern.adapter;

public interface Print {
	public abstract void printWeak();
	public abstract void printStrong();
}</pre>
<p>&nbsp;&nbsp; 2.<span style="font-size: small; color: #0000ff;">原有的内容</span></p>
<pre name="code" class="java">package com.pattern.adapter;

public class Banner {
	private String string;
	public Banner(String string) {
		this.string = string;
	}
	
	public void showWithParen() {
		System.out.println("$"+string+"$");
	}
	
	public void showWithAster() {
		System.out.println("*"+string+"*");
	}
}
</pre>
<p>&nbsp; <span style="font-size: small; color: #0000ff;">3.适配器，将原有的内容转换成我们需要的</span></p>
<pre name="code" class="java">package com.pattern.adapter;

/**
 * 适配器类
 * @author administrator
 */
public class PrintBanner extends Banner implements Print {
	
	public PrintBanner(String string) {
		//调用父类的构造函数
		super(string);
	}
	//输出减弱的字符串
	public void printStrong() {
		showWithParen();
	}
	//输出加强的字符串
	public void printWeak() {
		showWithAster();
	}

}

</pre>
<p>&nbsp; <span style="font-size: small; color: #0000ff;">4.测试类</span></p>
<pre name="code" class="java">package com.pattern.adapter;

public class Main {
	public static void main(String[] args) {
		Print p =new PrintBanner("Hello");
		//输出减弱字符
		p.printWeak();
		//输出加强字符
		p.printStrong();
	}
}
</pre>
<p>&nbsp;</p>
<p><span style="font-size: small;">&nbsp; 从Main类的源代码中完全看不出有Banner类,showWithParen()，showWtihAster()方法，好象只有人给笔记本电脑提供12V直流电，根据不知道它的原形(Adapter适配器的另一端)竟然是220V的交流电!</span></p>
<p>&nbsp;</p>
<p><span style="font-size: small;">&nbsp;下面的代码采用对象的委托实现程序示例1的功能</span></p>
<p><span style="font-size: small;">&nbsp; <span style="color: #0000ff;">程序救命2：</span></span></p>
<p><span style="font-size: small; color: #0000ff;">&nbsp; 1.注意这里的Print不再是接口，而是抽象类
<pre name="code" class="java">package com.pattern.adapter;

public abstract Print {
	public abstract void printWeak();
	public abstract void printStrong();
}</pre>
<p>&nbsp; 2.适配器，采用对象委托模式</p>
<pre name="code" class="java">package com.pattern.adapter;

/**
 * 适配器类
 * @author administrator
 */
public class PrintBanner extends Print {
	private Banner banner;
	public PrintBanner(String string) {
		this.banner = new Banner(string);
	}
	//输出减弱的字符串
	public void printStrong() {
		banner.showWithParen();
	}
	//输出加强的字符串
	public void printWeak() {
		banner.showWithAster();
	}
}

</pre>
<font size="3" color="#0000ff">
<p>&nbsp;</p>
</font></span></p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp; <span style="font-size: small;">测试类同上</span></p>
<p><span style="font-size: small;">&nbsp;&nbsp; </span></p>
<p><span style="font-size: small; color: #0000ff;">&nbsp; 设计思想：</span></p>
<p><span style="font-size: small;"><span style="color: #0000ff;">&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size: 10.5pt; color: #000000; font-family: 宋体; mso-ascii-font-family: Calibri; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-fareast; mso-hansi-font-family: Calibri; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA;">把一个类的接口变换成客户端所期待的另一种接口，从而使原本因接口原因不匹配而无法一起工作的两个类能够一起工作。适配类可以根据参数返还一个合适的实例给客户端。</span></span><span style="font-size: 10.5pt; color: #000000; font-family: 'Calibri','sans-serif'; mso-ascii-theme-font: minor-latin; mso-fareast-theme-font: minor-fareast; mso-hansi-theme-font: minor-latin; mso-bidi-font-family: 'Times New Roman'; mso-bidi-theme-font: minor-bidi; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA; mso-fareast-font-family: 宋体;"><br style="mso-special-character: line-break" /><br style="mso-special-character: line-break" /></span></span></p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/216150#comments" style="color:red;">已有 <strong>1</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 18 Jul 2008 14:48:47 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/216150</link>
        <guid>http://sunnylocus.javaeye.com/blog/216150</guid>
      </item>
          <item>
        <title>Java设计模式—迭代器(Iterator)</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/216074" style="color:red;">http://sunnylocus.javaeye.com/blog/216074</a>&nbsp;
          发表时间: 2008年07月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>1.Aggregate接口所声明的方法只有iterator方法一个，这是为了建立一个对对应聚合的 <br />iterator <br /></p>
<pre name="code" class="java">package com.pattern.iterator;

public interface Aggregate {
	public abstract Iterator iterator();
}
</pre>
<p><br /><br />2.iterator接口，执行元素递增，具有类似循环变量的功能。 <br /></p>
<pre name="code" class="java">package com.pattern.iterator;
public interface Iterator {
	public abstract boolean hasNext();
	public abstract Object next();
}
</pre>
<p><br /><br /><br />3. 书籍类 <br /></p>
<pre name="code" class="java">package com.pattern.iterator;
public class Book {
	private String name="";

	public Book(String name) {
		this.name = name;
	}
	
	/**
	 * 获得书籍名称
	 * @return String
	 */
	public String getName() {
		return name;
	}
}
</pre>
<p><br /><br />4.书架类 <br /></p>
<pre name="code" class="java">package com.pattern.iterator;
/**
 * 书架类
 * @author administrator
 */
public class BookShelf implements Aggregate{
	private Book[] books;
	private int last = 0;
	
	public BookShelf(int maxSize) {
		this.books = new Book[maxSize];
	}
	
	public Book getBookAt(int index) {
		return books[index];
	}
	
	//添加书籍
	public void appendBook(Book book) {
		this.books[last] = book;
		last++;
	}
	//获得书架存书的数量
	public int getLength() {
		return books.length;
	}
                //获得书架迭代器对象
	public Iterator iterator() {
		return new BookShelfIterator(this);
	}
	
}
</pre>
<p><br />5.书架迭代器类 <br /></p>
<pre name="code" class="java">package com.pattern.iterator;
public class BookShelfIterator implements Iterator{
	private BookShelf bookShelf;
	private int index;
	
	public BookShelfIterator(BookShelf bookShelf) {
		this.bookShelf = bookShelf;
		this.index = 0;
	}
	
	//检查是否还有下一本书
	public boolean hasNext() {
		if(index &lt; bookShelf.getLength()) {
			return true;
		}
		else {
			return false;
		}
	}
	//返回指定位置的书籍
	public Object next() {
		Book book = bookShelf.getBookAt(index);
		index ++;
		return book;
	}
}
</pre>
<p><br /><br /><br />6.测试类 <br /></p>
<pre name="code" class="java">package com.pattern.iterator;

public class Main {
	public static void main(String[] args) {
		//生成一个书架
		BookShelf bookShelf = new BookShelf(4);
		//向书架添加书籍
		bookShelf.appendBook(new Book("周恩来的晚年岁月"));
		bookShelf.appendBook(new Book("C++网络编程"));
		bookShelf.appendBook(new Book("J2EE网络编程精解"));
		bookShelf.appendBook(new Book("Java编程思想"));
		
		//获得书架迭代器
		Iterator it = bookShelf.iterator();
		while(it.hasNext()) {
			Book book = (Book)it.next();
			System.out.println(book.getName());
		}
	}
}
</pre>
<p><br /><br /><br />输出结果: <br /><br /><span style="color: #3366ff;">周恩来的晚年岁月 <br />C++网络编程 <br />J2EE网络编程精解 <br />Java编程思想</span> <br /><br /><span style="color: #0000ff;">迭代器设计恩想：</span> <br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff0000;">&nbsp; 迭代器可以顺序访问一个聚集中的元素而不必显露聚集的内部对象。多个对象聚在一起形成的总体称为聚集，聚集对象是能够包容一组对象的容器对象。迭代器模式将迭代逻辑封装到一个独立的对象中，从而与聚集本身隔开。迭代算法独立于聚集对象，修改迭代算法不会对聚集对象产生任何影响，实现程序的松耦合。 <br /></span></p>
<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/216074#comments" style="color:red;">已有 <strong>2</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 18 Jul 2008 11:52:12 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/216074</link>
        <guid>http://sunnylocus.javaeye.com/blog/216074</guid>
      </item>
          <item>
        <title>MyEclipse优化技巧</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/215993" style="color:red;">http://sunnylocus.javaeye.com/blog/215993</a>&nbsp;
          发表时间: 2008年07月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div id="context_main">
<h3><strong><span style="font-size: medium;">第一步: 取消自动validation</span></strong></h3>
<p><span style="font-size: medium;">validation有一堆，什么xml、jsp、jsf、js等等，我们没有必要全部都去自动校验一下，只是需要的时候才会手工校验一下！</span></p>
<p><strong><span style="font-size: medium;"><img src="http://news.newhua.com/Files/Remoteupfile/2008-4/18/windowslivewritermyeclipse-a5871-thumb.jpg" border="0" height="543" alt="1" style="width: 492px; height: 469px; border-width: 0px;" width="681" /> </span></strong></p>
<p><span><span style="font-size: medium;"><strong>取消方法：</strong><br /><span style="color: #0000ff;">windows&ndash;&gt;perferences&ndash;&gt;myeclipse&ndash;&gt;validation<br /></span>除开Manual下面的复选框全部选中之外，其他全部不选<br /><strong>手工验证方法：</strong><br />在要验证的文件上，单击鼠标右键&ndash;&gt;<span style="color: #0000ff;">myeclipse&ndash;&gt;run validation</span></span></span></p>
<h3><strong><span style="font-size: medium;">第二步：取消Eclipse拼写检查</span></strong></h3>
<p><span style="font-size: medium;">1、拼写检查会给我们带来不少的麻烦，我们的方法命名都会是单词的缩写，他也会提示有错，所以最好去掉，没有多大的用处</span></p>
<p><span style="font-size: medium; color: #0000ff;">windows&ndash;&gt;perferences&ndash;&gt;general&ndash;&gt;validation-&gt;editors-&gt;Text Editors-&gt;spelling</span></p>
<p><span style="font-size: medium;"><img src="http://news.newhua.com/Files/Remoteupfile/2008-4/18/windowslivewritermyeclipse-a5872-thumb.jpg" border="0" height="546" alt="2" style="width: 488px; height: 528px; border-width: 0px;" width="518" /></span></p>
<h3><strong><span style="font-size: medium;">第三步：取消myeclipse的启动项</span></strong></h3>
<p><span style="font-size: medium;">myeclipse会有很多的启动项，而其中很多我们都用不着，或者只用一两个，取消前面不用的就可以</span></p>
<p><span style="font-size: medium; color: #0000ff;">windows&ndash;&gt;perferences&ndash;&gt;general&ndash;&gt;startup and shutdown</span></p>
<p><span style="font-size: medium;"><img src="http://news.newhua.com/Files/Remoteupfile/2008-4/18/windowslivewritermyeclipse-a5873-thumb.jpg" border="0" height="600" alt="3" style="border-width: 0px;" width="416" /></span></p>
<h3><strong><span style="font-size: medium;">第四步：更改jsp默认打开的方式</span></strong></h3>
<p><span style="font-size: medium;">安装了myeclipse后，编辑jsp页面，会打开他的编辑页面，同时也有预览页面，速度很慢，不适合开发。所以更改之</span></p>
<p><span style="font-size: medium; color: #0000ff;">windows&ndash;&gt;perferences&ndash;&gt;general&ndash;&gt;editors-&gt;file associations</span></p>
<p><span style="font-size: medium;"><img src="http://news.newhua.com/Files/Remoteupfile/2008-4/18/windowslivewritermyeclipse-a5874-thumb.jpg" border="0" height="495" alt="4" style="width: 466px; height: 458px; border-width: 0px;" width="604" /></span></p>
<p><span style="font-size: medium;">在下方选择一种编辑器，然后点击左边的default按钮</span></p>
<p><span style="font-size: medium;">第五步：更改代码提示快捷键</span></p>
<p><span style="font-size: medium;">现在的代码提示快捷键，默认为ctrl+space，而我们输入法切换也是，所以会有冲突。谁叫myeclipse是外国人做的呢。。根本不需要切换输入法.</span></p>
<p><span style="font-size: medium; color: #0000ff;">windows&ndash;&gt;perferences&ndash;&gt;general&ndash;&gt;Keys</span></p>
<p><span style="font-size: medium;">更改 content assist 为 alt+/</span></p>
<p><span style="font-size: medium;">同时由于alt+/已经被word completion占用，所以得同时修改word completion的快捷键值</span></p>
<p><span style="font-size: medium;"><img src="http://news.newhua.com/Files/Remoteupfile/2008-4/18/windowslivewritermyeclipse-a5875-thumb.jpg" border="0" height="253" alt="5" style="width: 490px; height: 203px; border-width: 0px;" width="803" /></span></p>
<p><span style="font-size: medium;">好了,现在的速度及方便性是不是提高了。</span></p>
<p><span style="font-size: medium;">当然这只是对一种工具的熟悉而已，不存在什么技术含量，但俗话不是说</span></p>
<p><span style="font-size: medium;">&ldquo;磨刀不误砍柴工&rdquo;，有了方便的工具，对于我们写代码时的心情还是有所提高的...</span></p>
</div>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/215993#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 18 Jul 2008 09:03:26 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/215993</link>
        <guid>http://sunnylocus.javaeye.com/blog/215993</guid>
      </item>
          <item>
        <title>Tomcat输出流异常的解决</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/215787" style="color:red;">http://sunnylocus.javaeye.com/blog/215787</a>&nbsp;
          发表时间: 2008年07月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;&nbsp;&nbsp;&nbsp; 前几天做了一个jsp文件下载的页面，刚开始是直接链接到要下载的文件上，在装有像迅雷，网际快车下载软件没有问题，但在没有装这些软件的机器上会把文件直接打开，如果是一个带后缀名为.rar压缩文件后会直接打开,页面全是乱码。最后重新做了一遍，download.jsp页面接收文件的id,根据这个id号找到对应的文件所有在的路径，把要下载的文件转换成流输出,下载的功能实现了，不过每次下载文件tomcat都要报</p>
<p><span style="color: #ff0000;">java.lang.IllegalStateException:</span><span style="color: #800000;">getOutputStream() has already been called for this response</span></p>
<p>&nbsp;</p>
<p>查了好多的资料，终于明白了报错的原因</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在tomcat5下jsp中出现此错误一般都是在jsp中使用了输出流,没有处理好的原因。<br />具体的原因就是：<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在tomcat中jsp编译成servlet之后在函数<span style="color: #0000ff;">_jspService(HttpServletRequest request,HttpServletResponse response)</span>的最后有一段这样的代码<br /><span style="color: #0000ff;">finally {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);<br />&nbsp;&nbsp;&nbsp;&nbsp; }</span><br />这里是在释放在jsp中使用的对象，会调用response.getWriter(),因为这个方法是和response.getOutputStream()相冲突的！所以会出现以上这个异常。</p>
<p>&nbsp;</p>
<p>在使用完输出流以后加入下面两条语句<br />out.clear();<br />out = pageContext.pushBody();</p>
<p>&nbsp;</p>
<p>示例：download.jsp</p>
<pre name="code" class="java">//新建文件输入输出流
OutputStream output = null;
FileInputStream fis = null;
try{
    //新建File对象
    File f = new File("文件路径");
    //新建文件输入输出流对象
   output = response.getOutputStream();
    fis = new FileInputStream(f);
    //设置每次写入缓存大小
    byte[] buffer = new byte[1024];
    //把输出流写入客户端
    int i = =1;
    while((i = fis.read(b)) != -1){
      output.write(buffer, 0, i);
    }
    output.flush();
}
catch(Exception e){
    e.printStackTrace();
}
finally{
    if(fis != null){
      fis.close();
      fis = null;
    }
    if(output != null){
      output.close();
      output = null;
    }
    if(out != null){
    //下面这两行解决getOutputStream() has already been called for this response异常
      out.clear();
      out = pageContext.pushBody();
    }
}
</pre>
<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/215787#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 17 Jul 2008 14:46:21 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/215787</link>
        <guid>http://sunnylocus.javaeye.com/blog/215787</guid>
      </item>
          <item>
        <title>Red Hat Enterprise 4 中文乱码解决办法</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/215733" style="color:red;">http://sunnylocus.javaeye.com/blog/215733</a>&nbsp;
          发表时间: 2008年07月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp; 在用SSH登陆Linux操作系统，发现返回中文提示信息全是乱码，我看了下公司服务器linux配置信息，要修改 /etc/sysconfig目录下的 i18n文件</p>
<p>修改内容如图:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img src="../../upload/picture/pic/17972/aec32fea-523a-38e0-a989-a89337f39594.bmp" height="168" alt="" style="vertical-align: middle;" width="504" /></p>
<p>修改后重新启动，中文乱码解决...</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/215733#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 17 Jul 2008 12:00:51 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/215733</link>
        <guid>http://sunnylocus.javaeye.com/blog/215733</guid>
      </item>
          <item>
        <title>Linux系统sendmail启动速度慢的解决办法</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/215629" style="color:red;">http://sunnylocus.javaeye.com/blog/215629</a>&nbsp;
          发表时间: 2008年07月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在大部分Linux发行版本中，sendmail这个古老的邮件系统包是默认安装的，装完系统后，重启时，不少兄弟遇到在启动过程中，到了启动sendmail服务的时候就停止了，没有耐性和经验的朋友这时候可能会以为系统出故障或者系统没有装好，其实既不是系统出故障，一般也不是系统没有安装好，而是系统sendmail的时候在查询你设置的主机名的A记录或反向域名记录，由于全球9台DNS根系统都在美国，这个时候会去查询本机主机名对应的dns A记录，特别时你安装系统时设置的一些&ldquo;奇怪&rdquo;的主机名的时候，比如webserver等等之类的，这个时候sendmail会去做这个操作过程。</p>
<pre name="code" class="C">Apr 28 13:41:36 webserver sendmail[3494]: gethostby*.getanswer: asked for "webserver IN AAAA", got type "A"

Apr 28 13:42:36 webserversendmail[3499]: gethostby*.getanswer: asked for "webserver IN AAAA", got type "A"

Apr 28 13:43:37 webserver sendmail: sendmail startup succeeded

Apr 28 13:43:37 webserver sm-msp-queue[3509]: gethostby*.getanswer: asked for "webserver IN AAAA", got type "A"</pre>
<p><br /><br />&nbsp;&nbsp;&nbsp;&nbsp; 运气好，我的意思是你的&ldquo;RP&rdquo;好，呵呵，查询比较快，你感觉不到异样，&ldquo;RP&rdquo;不好，少则一到两分钟，多则四到五分钟，而且要命的是不报任何错误信息，这个时间大大超过了我们能忍受的&ldquo;8s&rdquo;时间了，心里承受力差的兄弟就要受煎熬了。 <br /><br />知道了问题的症结，就可以对症下药了，比如我们可以修改系统配置文件<strong>/etc/hosts </strong><br /><br />让sendmial绕过查询远程主机，这里给出一种最简单的方法，给主机设置一个别名 <br /><br />修改/etc/hosts ，未修改之前 <br /><strong>127.0.0.1 localhost.localdomain localhost</strong> <br />修改成 <br /><strong>127.0.0.1 localhost.localdomain localhost 主机名称</strong></p>
<p><span style="color: #0000ff;">查看本机的主机名称的命令是:&nbsp; hostname</span><br />再次重新启动sendmail看看</p>
<pre name="code" class="C">[root@webserver ~]# service sendmail restart
Shutting down sm-client: [ OK ]
Shutting down sendmail: [ OK ]
Starting sendmail: [ OK ]
Starting sm-client: [ OK ]</pre>
<pre name="code" class="C">启动时间已经到秒级了。 

</pre>
<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/215629#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 17 Jul 2008 09:07:42 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/215629</link>
        <guid>http://sunnylocus.javaeye.com/blog/215629</guid>
      </item>
          <item>
        <title>数据库备份与恢复</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/166475" style="color:red;">http://sunnylocus.javaeye.com/blog/166475</a>&nbsp;
          发表时间: 2008年03月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <strong>1、备份数据库&nbsp; </strong><br /> 下例显示使用 BACKUP 和 RESTORE 语句创建 Northwind 数据库的复本。MOVE 语句使数据和日志文件还原到指定的位置。 <br /><pre name="code" class="sql">BACKUP DATABASE Northwind 
   TO DISK = 'c:\Northwind.bak'
GO</pre><br /><strong>2、数据库恢复</strong><br />&nbsp;&nbsp; A.附加数据库	<br /><pre name="code" class="sql">   CREATE DATABASE sunnyShop
   ON PRIMARY (FILENAME = 'F:\sunnyShop\DB\sunnyShop.mdf')
   FOR ATTACH
  GO
 </pre><br />&nbsp;&nbsp; B.还原用bcackup备份的数据库<br />&nbsp;&nbsp;&nbsp;&nbsp; 下例还原完整数据库和事务日志，并将已还原的数据库移动到 E盘根目录下<br /><pre name="code" class="sql">RESTORE DATABASE TestDB 
   FROM DISK = 'c:\Northwind.bak'
   WITH MOVE 'Northwind' TO 'E:\test.mdf',
   MOVE 'Northwind_log' TO 'E:test.ldf'
   GO</pre>
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/166475#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 01 Mar 2008 18:19:02 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/166475</link>
        <guid>http://sunnylocus.javaeye.com/blog/166475</guid>
      </item>
          <item>
        <title>数据库创建</title>
        <author>sunnylocus</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sunnylocus.javaeye.com">sunnylocus</a>&nbsp;
                    链接：<a href="http://sunnylocus.javaeye.com/blog/166474" style="color:red;">http://sunnylocus.javaeye.com/blog/166474</a>&nbsp;
          发表时间: 2008年03月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <strong>一、	数据库创建</strong><br /><span style="color: blue">A．创建指定数据库文件和事务日志文件的数据库</span><br />&nbsp;&nbsp;&nbsp; 下面的示例创建名为 sunnyShop 的数据库。因为没有使用关键字 PRIMARY，第一个文件 (sunnyShop.mdf) 成为主文件。因为 sunnyShop_dat 文件的 SIZE 参数没有指定 MB 或 KB，因此默认为 MB，以兆字节为单位进行分配。sunnyShop.ldf文件以兆字节为单位进行分配，因为 SIZE 参数中显式声明了 MB 后缀。<br /><pre name="code" class="sql">create database sunnyShop
on PRIMARY
(
	NAME = sunnyShop_date,
	FILENAME='F:\sunnyShop.mdf',
	SIZE = 10,
	MAXSIZE = UNLIMITED,
	FILEGROWTH = 5
)
LOG ON
(
	NAME='sunnyShop_dat',
	FILENAME='F:\sunnyShop.ldf',
	SIZE =5MB,
	MAXSIZE = 25MB,
	FILEGROWTH =5MB
)
GO
USE sunnyShop
GO</pre><br /><br />	 <br /><span style="color: blue">B.创建指定多个数据库文件和多个事务日志文件的数据库</span><br />&nbsp;&nbsp;&nbsp; 下面的示例使用三个 100 MB 的数据文件和两个 100 MB 的事务日志文件创建了名为 Archive 的数据库。主文件是列表中的第一个文件，并使用 PRIMARY 关键字显式指定。事务日志文件在 LOG ON 关键字后指定。注意 FILENAME 选项中所用的文件扩展名：主要数据文件使用 .mdf，次要数据文件使用 .ndf，事务日志文件使用 .ldf。<br /><pre name="code" class="sql">USE master
GO
CREATE DATABASE Archive 
ON
PRIMARY ( NAME = Arch1,
      FILENAME = 'c:\program files\microsoft sql    server\mssql\data\archdat1.mdf',
      SIZE = 100MB,
      MAXSIZE = 200,
      FILEGROWTH = 20),
( NAME = Arch2,
   FILENAME = 'c:\program files\microsoft sql server\mssql\data\archdat2.ndf',
   SIZE = 100MB,
   MAXSIZE = 200,
   FILEGROWTH = 20),
( NAME = Arch3,
   FILENAME = 'c:\program files\microsoft sql server\mssql\data\archdat3.ndf',
   SIZE = 100MB,
   MAXSIZE = 200,
   FILEGROWTH = 20)
LOG ON 
( NAME = Archlog1,
   FILENAME = 'c:\program files\microsoft sql server\mssql\data\archlog1.ldf',
   SIZE = 100MB,
   MAXSIZE = 200,
   FILEGROWTH = 20),
( NAME = Archlog2,
   FILENAME = 'c:\program files\microsoft sql server\mssql\data\archlog2.ldf',
   SIZE = 100MB,
   MAXSIZE = 200,
   FILEGROWTH = 20)
GO</pre><br /><br /><span style="color: blue">C.创建简单数据库文件</span><br /><br />&nbsp;&nbsp;&nbsp; 本例创建名为 Products 的数据库，并指定单个文件。指定的文件成为主文件，并会自动创建一个 1 MB 的事务日志文件。因为主文件的 SIZE 参数中没有指定 MB 或 KB，所以主文件将以兆字节为单位进行分配。因为没有为事务日志文件指定 &lt;filespec>，所以事务日志文件没有 MAXSIZE，可以增长到填满所有可用的磁盘空间为止。<br /><pre name="code" class="sql">USE master
GO
CREATE DATABASE Products
ON 
( NAME = prods_dat,
   FILENAME = 'c:\program files\microsoft sql server\mssql\data\prods.mdf',
   SIZE = 4,
   MAXSIZE = 10,
   FILEGROWTH = 1 )
GO</pre>参数释义:<br />Maxsize = unlimited&nbsp;&nbsp; 对数据库大小不作限制，直到数据库填满磁盘为止<br />Filegrowth:指定中定义的文件的增长增量。文件的 FILEGROWTH 设置不能超过 MAXSIZE 设置。
          <br/><br/>
          <span style="color:red;">
            <a href="http://sunnylocus.javaeye.com/blog/166474#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 01 Mar 2008 18:10:32 +0800</pubDate>
        <link>http://sunnylocus.javaeye.com/blog/166474</link>
        <guid>http://sunnylocus.javaeye.com/blog/166474</guid>
      </item>
      </channel>
</rss>