??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲αv在线精品糸列,亚洲阿v天堂在线2017免费,亚洲av无码不卡私人影院http://www.tkk7.com/dunkbird/category/30985.html路O漫其修远兮,向ְ上下而求? zh-cnSun, 05 Apr 2015 15:34:59 GMTSun, 05 Apr 2015 15:34:59 GMT60Q{Q关于Spring中ApplicationContext的说?/title><link>http://www.tkk7.com/dunkbird/articles/424061.html</link><dc:creator>大鸟</dc:creator><author>大鸟</author><pubDate>Thu, 02 Apr 2015 07:32:00 GMT</pubDate><guid>http://www.tkk7.com/dunkbird/articles/424061.html</guid><wfw:comment>http://www.tkk7.com/dunkbird/comments/424061.html</wfw:comment><comments>http://www.tkk7.com/dunkbird/articles/424061.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/dunkbird/comments/commentRss/424061.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/dunkbird/services/trackbacks/424061.html</trackback:ping><description><![CDATA[<div>http://blog.sina.com.cn/s/blog_5d6571df0100yaa5.html<br /><br /><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #464646; font-family: simsun; background-color: #bcd3e5;">一、简单的用ApplicationContext做测试的?获得Spring中定义的Bean实例(对象).可以?</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #464646; font-family: simsun; background-color: #bcd3e5;">ApplicationContext ac = new ClassPathXmlApplicationC<wbr><wbr>ontext("applicationContext.xml");<br />RegisterDAO registerDAO = (RegisterDAO)ac.getBean("RegisterDAO");</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #464646; font-family: simsun; background-color: #bcd3e5;">如果是两个以?<br />ApplicationContext ac = new ClassPathXmlApplicationC<wbr><wbr>ontext(new String[]{"applicationContext.xml","dao.xml"});<br /></p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #464646; font-family: simsun; background-color: #bcd3e5;">或者用通配W?<br />ApplicationContext ac = new ClassPathXmlApplicationC<wbr><wbr>ontext("classpath:/*.xml");</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #464646; font-family: simsun; background-color: #bcd3e5;"><br />二、ClassPathXmlApplicationC<wbr><wbr>ontext[只能L在web-info/classes目录下的配置文g]和FileSystemXmlApplication<wbr><wbr>Context的区?br /></p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #464646; font-family: simsun; background-color: #bcd3e5;">classpath:前缀是不需要的,默认是指项目的classpath路径下面;<br />如果要用绝对\?需要加上file:前缀表示q是l对路径;</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #464646; font-family: simsun; background-color: #bcd3e5;">对于FileSystemXmlApplication<wbr><wbr>Context:<br />默认表示的是两种:</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #464646; font-family: simsun; background-color: #bcd3e5;">1.没有盘符的是目工作路径,即项目的根目?<br />2.有盘W表C的是文件绝对\?</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #464646; font-family: simsun; background-color: #bcd3e5;">如果要用classpath路径,需要前~classpath:</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #464646; font-family: simsun; background-color: #bcd3e5;">public class HelloClient {</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #464646; font-family: simsun; background-color: #bcd3e5;">protected static final Log log = LogFactory.getLog(HelloClient.class);</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #464646; font-family: simsun; background-color: #bcd3e5;">public static void main(String[] args) {<br />// Resource resource = new ClassPathResource("appcontext.xml");<br />// BeanFactory factory = new XmlBeanFactory(resource);</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #464646; font-family: simsun; background-color: #bcd3e5;">// 用classpath路径<br />// ApplicationContext factory = new ClassPathXmlApplicationC<wbr><wbr>ontext("classpath:appcontext.xml");<br />// ApplicationContext factory = new ClassPathXmlApplicationC<wbr><wbr>ontext("appcontext.xml");</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #464646; font-family: simsun; background-color: #bcd3e5;">// ClassPathXmlApplicationC<wbr><wbr>ontext使用了file前缀是可以用绝对\径的<br />// ApplicationContext factory = new ClassPathXmlApplicationC<wbr><wbr>ontext("file:F:/workspace/example/src/appcontext.xml");</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #464646; font-family: simsun; background-color: #bcd3e5;">// 用文件系l的路径,默认指项目的根\?br />// ApplicationContext factory = new FileSystemXmlApplication<wbr><wbr>Context("src/appcontext.xml");<br />// ApplicationContext factory = new FileSystemXmlApplication<wbr><wbr>Context("webRoot/WEB-INF/appcontext.xml");<br /><br /></p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #464646; font-family: simsun; background-color: #bcd3e5;">// 使用了classpath:前缀,q样,FileSystemXmlApplication<wbr><wbr>Context也能够读取classpath下的相对路径<br />// ApplicationContext factory = new FileSystemXmlApplication<wbr><wbr>Context("classpath:appcontext.xml");<br />// ApplicationContext factory = new FileSystemXmlApplication<wbr><wbr>Context("file:F:/workspace/example/src/appcontext.xml");</p><p style="margin-top: 0px; margin-right: 0px; margin-left: 0px; padding: 0px; border: 0px; list-style: none; word-wrap: normal; word-break: normal; color: #464646; font-family: simsun; background-color: #bcd3e5;">// 不加file前缀<br />ApplicationContext factory = new FileSystemXmlApplication<wbr><wbr>Context("F:/workspace/example/src/appcontext.xml");<br />IHelloWorld hw = (IHelloWorld)factory.getBean("helloworldbean");<br />log.info(hw.getContent("luoshifei"));<br />}<br />}</p></div><img src ="http://www.tkk7.com/dunkbird/aggbug/424061.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/dunkbird/" target="_blank">大鸟</a> 2015-04-02 15:32 <a href="http://www.tkk7.com/dunkbird/articles/424061.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JavaGUI应用E序部vhttp://www.tkk7.com/dunkbird/articles/312169.html大鸟大鸟Fri, 05 Feb 2010 23:37:00 GMThttp://www.tkk7.com/dunkbird/articles/312169.htmlhttp://www.tkk7.com/dunkbird/comments/312169.htmlhttp://www.tkk7.com/dunkbird/articles/312169.html#Feedback0http://www.tkk7.com/dunkbird/comments/commentRss/312169.htmlhttp://www.tkk7.com/dunkbird/services/trackbacks/312169.htmlJavaGUI应用E序部v


JavaGUIE序发布分类

 1)  AppletQ可以嵌入到览器中Q通过|页的方式展C给用户

 2)  application Q有两种发布方式

  ü 打包成jar包通过bat的方式运行,或者通过W三方Y件打成exe(后箋会再详细介绍)

  ü 通过Java Web Start的方式发布到服务器端Q通过JNLPq行

 相对来说W二U方式可能更好一些,免除了更新的ȝ?/span>

 用applet或者jws的方式发布,大部分都需要数字签名?br />



Z么要{֐

 其实{֐不是必须的,如果你的E序只是单纯的绘图,昄Q只要不讉K|络资源也不讉K本地文gQ是不用{֐的,
 但是如果要访问本地或|上资源必ȝ名,
 比如d本地文g或者访问数据库Q这是由java的沙机制决定的Q即jvm内部有一l安全检查规则,要通过查之后才能访问特定资源?/span>

 如果要突破这个规则,可以有两个方?

 1) 修改jre权限文g如下

  java.policy为grant {
   permission java.security.AllPermission;
        };

  一般权限文件的目录如下C:"Program Files"Java"jre6"lib"security

  但是修改每个客户端的权限文gQ无Z旉q是操作上都是很ȝ的?/span>

 2)  {֐Q意思就是告诉用Pq个E序是谁发布的,是不是能信QQ如果客L(fng)定,okQ这个applet或者jws可以访问外部资源了?br />


如何{֐

 1)首先保你已l完全安装了Java2的环境,有keytool工具Q它位于JDK的bin目录下。这一般不会有问题?/span>

 2)到Dos状态下Q进入你需发布应用E序的jar包所在的目录Q运行下面这句话
   keytool -genkey -keystore myKeystore -alias jwstest -validity 1000
      它将会提CZ输入用户名、密码等Q按照提C随便输入即可,不输入直接回车即可,
   但一定要C密码。运行结束它?yu)会在当前\径下创徏名ؓmyKeystore的文件?/span>

 3)如果你想查看一下刚才生成的myKeystore文g的内容,可以使用下面q句话:
  keytool -list -keystore myKeystore
  昄出来应该cM如下Q?br />   Keystore type: jks
  Keystore provider: SUN
  Your keystore contains 1 entry:
  jwstest, Tue Nov 23 19:29:32 PST 2001, keyEntry,
  Certificate fingerprint (Test):
  C3:A9:CD:F3:D3:AC:4D:3F:3C:5B:AF:9E:CF:0D:46:5C

 4)对你需发布应用E序的jar包进行签名,q行下面q句话:
  jarsigner -keystore myKeystore yourtest.jar jwstest
  其中yourtest.jar是你的jar包名Q你需要修改它Q别的就不必修改了?br />   q行时会提示你输入密码,是你刚才在生成myKeystore文g时设定的密码?br />



如果有很多jar包怎么?/span>

 在开发的q程中很可能会引用到W三方的jar包,而第三方的jar包又可能引用到其它的Q所以可能有很多的jar包,需要和applet一起发布,有两个方?br />   1) 分别打包{֐Q用于包比较少Q比如只??个的情况
        2) ?把applet的jar包签名,让用L(fng)认访问授权,applet已经被用h权,那么可以在applet里改变安全管理器QSecurityManagerQ?br />    只需要承SecurityManagerc,创徏自己的安全管理器c,然后覆盖checkPermissionҎ(gu)Q允许访问Q何资源?br />    在applet的initҎ(gu)中调用System.setSecurityManager把安全管理器讄为我们自定义的即可?/span>


 class CustomManager extends SecurityManager {
  public void checkPermission(Permission perm, Object context) {
  }
  public void checkPermission(Permission perm) {
  }
 }
 

其它一些相兌料如?/span>

 JDK中keytool常用命o

 -genkey      在用户主目录中创Z个默认文?.keystore",q会产生一个mykey的别名,mykey中包含用L(fng)公钥、私钥和证书
 -alias       产生别名
 -keystore    指定密钥库的名称(产生的各cM息将不在.keystore文g?br />  -keyalg      指定密钥的算?nbsp;  
 -validity    指定创徏的证书有效期多少?br />  -keysize     指定密钥长度
 -storepass   指定密钥库的密码
 -keypass     指定别名条目的密?br />  -dname       指定证书拥有者信?例如Q?nbsp; "CN=sagely,OU=atr,O=szu,L=sz,ST=gd,C=cn"
 -list        昄密钥库中的证书信?nbsp;     keytool -list -v -keystore sage -storepass ....
 -v           昄密钥库中的证书详l信?br />  -export      别名指定的证书导出到文?nbsp; keytool -export -alias caroot -file caroot.crt
 -file        参数指定导出到文件的文g?br />  -delete      删除密钥库中某条?nbsp;         keytool -delete -alias sage -keystore sage
 -keypasswd   修改密钥库中指定条目口o    keytool -keypasswd -alias sage -keypass .... -new .... -storepass ... -keystore sage
 -import      已{֐数字证书导入密钥?nbsp; keytool -import -alias sage -keystore sagely -file sagely.crt
     导入已签名数字证书用keytool -list -v 以后可以明显发现多了认证N度,q且把整个CA铑օ部打印出来?/span>

 Keytool 是安全钥匙与证书的管理工?它管理一个存储了U有钥匙和验证相应公共钥匙的与它们相兌的X.509 证书铄keystore(相当一个数据库).

 Keytool 是一个有效的安全钥匙和证书的理工具. 它能够用户使用数字{֐来管理他们自qU有/公共钥匙?理用来作自我鉴定的相关的证?理数据完整性和鉴定服务.它还能用户在通信时缓存它们的公共钥匙.

 一个证书是某一实体(个h,公司{?的数字签?指出其他实体的公共钥?或其他信?的详l的?当数据被{֐?q个{֐信息被用来检验数据的完整性和真实?完整性指数据没有被修改和改,真实性指数据从Q何生和{֐的一方真正的传输到达.

 Keytool 把钥匙和证书储存C个keystore.默Q的实现keystore的是一个文?它用一个密码保护钥?

 而另外的一个工具jarsigner用keystore中的信息产生或检验Java aRchive(jar文g)中的数字{֐.

 Keystore有两个不同的入口:

 1.钥匙入口:保存了非常敏感的加密的钥匙信?q且是用一个保护的格式存储以防止未被授权的讉K.以这UŞ式存储的钥匙是秘密钥?或是一个对应证书链中公有钥匙的U有钥匙.

 2.信Q证书入口:包含一个属于其他部分的单一公共钥匙证书.它之所以被UCؓ"信Q证书",是因为keystore信Q的证书中的公共钥匙真正属于证书所有者的w䆾识别.

 Keystore的别?

 所有的keystore入口(钥匙和信任证书入?是通过唯一的别名访?别名?不区分大写?如别名Hugo和hugo指向同一个keystore入口.

 可以在加一个入口到keystore的时候?genkey参数来生一个钥匙对(公共钥匙和私有钥?时指定别?也可以用-import参数加一个证书或证书铑ֈ信Q证书.

 ?

 keytool -genkey -alias duke -keypass dukekeypasswd

 其中duke为别?dukekeypasswd为duke别名的密?q行命o的作用是产生一个新的公?U有钥匙?

 假如你想修改密码,可以?

 keytool -keypasswd -alias duke -keypass dukekeypasswd -new newpass

 旧密码dukekeypasswd改ؓnewpass.

 Keystore的?

 1.当?genkey ?import?identitydb命od数据C个keystore,而当q个keystore不存在时,产生一个keystore.默认名是.keystore,存放到user-home目录.

 2.当用-keystore指定?生指定的keystore.

 Keystore的实?

 Keytool cM于java.security包下,提供一个非常好的接口去取得和修改一个keystore中的信息. 目前有两个命令行:keytool和jarsinger,一个GUI工具Policy 可以实现keystore.׃keystore是公开?用户可以用它写一些额外的安全应用E序.

 Keystoreq有一个sun公司提供的內在实?它把keystore作ؓ一个文件来实现.利用了一个keystorecd(格式)"JKS".它用单独的密码保护每一个私有钥?也用可能不同的密码保护整个keystore的完整?

 支持的算法和钥匙大小:

 keytool允许用户指定钥匙对和注册密码服务供应者所提供的签名算?~省的钥匙对产生法?DSA".假如U有钥匙?DSA"cd,~省{֐法?SHA1withDSA",假如U有钥匙?RSA"cd,~省法?MD5withRSA".

 当生一个DSA钥匙?钥匙必须?12-1024位之?对Q何算法的~省钥匙大小?024?

 证书:

 一个证书是一个实体的数字{֐,指出其他实体的公共钥匙有明确的?

 1.公共钥匙 :是同一个详l的实体的数字关?q有意让所有想同这个实体发生信dpȝ其他实体知道.公共钥匙用来验签?

 2.数字{֐:假如数据已被{֐,q用w䆾存储在一个实体中,一个签名能够证明这个实体知道这个数?q个数据用实体私有钥匙签名ƈ递交;

 3.w䆾:知道实体的方?在一些系l中w䆾是公共钥?其他pȝ中可以是从一个X.509名字的邮件地址的Unix UID来的M东西;

 4.{֐:一个签名用用实体私有钥匙来计算某些加密数据;

 5.U有钥匙:是一些数?每一个私有钥匙只能被特定的拥有该U有钥匙的实体知?U有和公共钥匙存在所有用公共钥匙加密的系l的钥匙对中.一个公共钥匙加?如DSA),一个私有钥匙与一个正的公共钥匙通信.U有钥匙用来计算{֐.

 6.实体:一个实体可以是一个h,一个组l?一个程?一台计机,一个商?一个银?或其他你想信ȝ东西.

 Keytool应用实例:

 1.产生一个keystore:

 keytool -genkey -alias User(keystore的别? -keyalg RSA -validity 7 -keystore keystore(指定keystore).

 q行q个命o,pȝ提示:

 Enter keystore password:yourpassword(输入密码)

 What is your first and last name?

 [Unknown]: your name(输入你的名字)

 What is the name of your organizational unit?

 [Unknown]:your organizational(输入你所在组l单位的名字)

 What is the name of your organization?

 [Unknown]:your organization name (输入你所在组l的名字)

 What is the name of your City or Locality?

 [Unknown]:your city name(输入所在城市的名字)

 What is the name of your State or Province?

 [Unknown]:your provice name(输入所在省份名?

 What is the two-letter country code for this unit?

 [Unknown]:cn(输入国家名字)

 Is CN=your name, OU=your organizaion, O="your organization name",

 L=your city name, ST=your province name, C=cn correct?

 [no]: yes

 2.查一个keystore:

 keytool -list -v -keystore keystore

 Enter keystore password:your password(输入密码)

 显Ckeystore內容?

 Keystore type: jks

 Keystore provider: SUN

 Your keystore contains 1 entry

 Alias name: yourname

 Creation date: Dec 20, 2001

 Entry type: keyEntry

 Certificate chain length: 1

 Certificate[1]:

 Owner: CN=yourname, OU=your organization, O="your organization name",

 L=your city name, ST=your province name, C=CN

 Issuer: CN=Duke, OU=Java Software, O="Sun Microsystems, Inc.", L=Palo Alto, ST=CA, C=US

 Serial number: 3c22adc1

 Valid from: Thu Dec 20 19:34:25 PST 2001 until: Thu Dec 27 19:34:25 PST 2001

 Certificate fingerprints:

 MD5: F1:5B:9B:A1:F7:16:CF:25:CF:F4:FF:35:3F:4C:9C:F0

 SHA1: B2:00:50:DD:B6:CC:35:66:21:45:0F:96:AA:AF:6A:3D:E4:03:7C:74

 3.输出keystoreC个文?testkey:

 keytool -export -alias duke -keystore keystore -rfc -file testkey

 pȝ输出:

 Enter keystore password:your password(输入密码)

 Certificate stored in file < td>

 4.输入证书C个新的truststore:

 keytool -import -alias dukecert -file testkey -keystore truststore

 Enter keystore password:your new password.(输入truststore新密?

 5.查truststore:

 keytool -list -v -keystore truststore

 pȝ显Ctruststore的信?

 现在可以用适当的keystoreq行你的应用E序.?

 java -Djavax.net.ssl.keyStore=keystore -Djavax.net.ssl.keyStorePassword=password Server

 ? java -Djavax.net.ssl.trustStore=truststore

 -Djavax.net.ssl.trustStorePassword=trustword Client


 Q{Qby

   张涛
    zht_dream@hotmail.com
 



大鸟 2010-02-06 07:37 发表评论
]]>
优秀E序员的十个?fn)?/title><link>http://www.tkk7.com/dunkbird/articles/308197.html</link><dc:creator>大鸟</dc:creator><author>大鸟</author><pubDate>Mon, 04 Jan 2010 10:06:00 GMT</pubDate><guid>http://www.tkk7.com/dunkbird/articles/308197.html</guid><wfw:comment>http://www.tkk7.com/dunkbird/comments/308197.html</wfw:comment><comments>http://www.tkk7.com/dunkbird/articles/308197.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/dunkbird/comments/commentRss/308197.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/dunkbird/services/trackbacks/308197.html</trackback:ping><description><![CDATA[在这个世界上Q有数百万的人热衷于软g开发,他们有很多名字,如:软g工程师(Software EngineerQ,E序员(ProgrammerQ,~码人(CoderQ,开发h员(DeveloperQ。经q一D|间后Q这些h也许能够成ؓ一个优U的编码h员,他们会非常熟(zhn)如何用计算a来完成自q工作。但是,如果你要成ؓ一个优U的程序员Q你q可以需要有几g事你需要注意,如果你能让下面十个条目成Z的习(fn)惯,那么你才能真正算得上是优UE序员? <p>1. <strong>学无止境</strong>。就是你有?0q以上的E序员经历,你也得要使劲地学?fn),因ؓ你在计算个充满一创造力的领域,每天都会有很多很多的C物出现。你需要跟上时代的步伐。你需要去了解新的E序语言Q以及了解正在发展中的程序语aQ以及一些编E框架。还需要去阅读一些业内的新闻QƈC些热门的C֌d与在U的讨论Q这样你才能明白和了解整个Y件开发的势。在国内Q一些著名的C֌例如QCSDNQITPUBQCHINAUINX{等Q在国外Q徏议你l常上一上digg.comȝ看各UBLOG的聚合?/p> <p></p> <p>2. <strong>掌握多种语言</strong>。程序语aL有其最适合的领域。当你面寚w要解决的问题Ӟ你需要找C个最适合的语a来解册些问题。比如,如果你需要性能Q可能C/C++是首选,如果你需要跨q_Q可能Java是首选,如果你要写一个Web上的开发程序,那么PHPQASPQAjaxQJSP可能会是你的选择Q如果你要处理一些文本ƈ和别的应用交互,可能Perl, Python会是最好的。所以,׃些时间去探烦一下其它你q熟(zhn)的E序语言Q能让你的眼界变宽,因ؓ你被武装得更好,你思考问题也更为全面,q对于自己和目都会有好的帮助?/p> <p>3. <strong>理性面对不同的操作pȝ或技?/strong>。程序员们L有自己心目中无可比拟的技术和操作pȝQ有的h喜欢UbuntuQ有的h喜欢DebianQ还有的人喜ƢWindowsQ以及FreeBSDQMacOSX或Solaris{等。看看我的BLOG(<a onclick="pageTracker._trackPageview('/outgoing/blog.csdn.net/haoel?referer=http%3A%2F%2Fwww.google.com%2Freader%2Fview%2F');" >http://blog.csdn.net/haoel</a>)中的那篇?a onclick="pageTracker._trackPageview('/outgoing/blog.csdn.net/haoel/archive/2007/03/19/1533720.aspx?referer=http%3A%2F%2Fwww.google.com%2Freader%2Fview%2F');" target="_blank">其实Unix很简?/a>》后的回复你q道程序员们在l护赯q忠爱时的那䆾执着了。只有一部分优秀的程序员明白不同操作pȝ的优势和长处和短处,q样Q在pȝ选型的时候,才能做到真正的客观和公正Q而不会让情A影响到自己。同P语言也是一P有太多的E序员L喜欢U缠于语a的对比,如:Java和Perl。哪个刚刚出道的E序员没有争论去cM的话题呢Q比如VC++和Delphi{等。争些东西只能表明自q肤浅和Q燥。优U的程序ƈ不会执着于这些,而是能够理性的分析和理心地面对Q从而才能客观地做出正确的选择?/p> <p>4. <strong>别把自己框在单一的开发环境中?/strong> 再一ơ,正如上面所qͼ每个E序员都有自己忠q工具和技术,有的喜欢老的Q比如我喜ƢVi~辑E序Q,而有的喜Ƣ新的比如gedit或是Emacs{。有的喜Ƣ用像VC++一L(fng)囑Ş界面的调试器Q而我更喜ƢGDB命o行方面的调式器。等{等{。程序员在用什么样的工具上的争吗Q到处都是啊。用什么样的工h来无所谓,只要你能更好更快地达C的目的。但是有一Ҏ(gu)优秀E序员都应该了解的——那是应该d试一下别的工作环境。没有比较,你永q不知道谁好谁不好,你也永远不知道你所不知道的?/p> <p>5. <strong>使用版本理工具理你的代码?/strong>千万不要告诉我你不知道源码的版本理Q如果你的团队开发的源代码ƈ没有版本理pȝQ那么我要告诉你Q你的Y件开发还处于矛_时代。赶快用一个版式本理工具吧。CVS 是一个看上去qxE无奇的版本工P但它是被使用最q的版本理pȝQSubversion 是CVS的一个升U版Q其正在开始接CVS的领地。Git 又是一个不同的版本理工具。还有Visual SourceSafe{。用什么样的版本管理工具依赖于你的团队的大和地理分布Q你也许正在使用最有效率或最没有效率的工h理你的源代码。但一个优U的程序员L会用一ƾ源码版本管理工h理自己的代码。如果你要我推荐一个,我推荐你使用开源的Subversion?/p> <p>6. <strong>是一个优U的团队成员?/strong> 除非你喜Ƣ独奏,除非你是孤胆英雄。但我想告诉你,今天Q可能没有一个成熟的软g是你一个h能做的到的,你可能是你团队中最牛的大拿Q但qƈ不意味着你就是好的团队成员。你的能力只有放C个团队中才能施展开来。你在和你的团队成员交流中有CD吗?你是否经常和他们沟通,q且大家都喜Ƣ和你在一赯论问题?想一想一个球队吧,你是q个队中好的成员吗?当别人看C在场上的跑动Ӟ当别人看C的传球和接球和抢断时Q你的团员成员能因ؓ你的动作受到鼓舞吗?</p> <p>7. <strong>把你的工作变成文档?/strong> q一条目当然包括了在代码中写注释Q但那还仅仅不够Q你q需要做得更多。有良好的注释风格的代码是一个文档的基础Q他能够让你和你的团队容易的明白你的意图和想法。写下文档,q不仅仅是怕我们忘了当时的xQ而且q是一U团队的ȝ交流的方法,更是一U知识传递的Ҏ(gu)。记录下你所知道的一切会是一个好的习(fn)惯。因为,我相信你不希望别人L在你最忙的时候来打断你问问题Q或是你在休假的时候接到公司的?sh)话来询问你问题。而你自己如果老是守着自己的东西,其结果只可能是让你自己长旉地深陷在q块东西内,而你更本不可以d更多的事情。包括向上的晋升。你可能以ؓ“教会徒弟能饿d?#8221;Q但我告诉你Q你的保守会让你失去更多更好的东西,请你怿我,我绝不是在这里思h听闻?/p> <p>8. <strong>注意备䆾和安全?/strong> 可能你觉得这是一?#8220;废话”Q你已明白了备䆾的重要性。但是,我还是要在这里提出,丢失东西是我们h生中的一部䆾Q你L会丢东西Q这点你永远无法避免。比如:你的W记本电(sh)脑被人偷了,你的盘损坏了,你的?sh)脑中病毒了Q你的系l被人入侵了Q甚x个大D烧了Q等{,{等。所以,做好备䆾工作是非帔R帔R要的事情Q硬盘是不可信的Q所以定期的d光盘或是带可能会是一个好的方法,|络也是不可信的Q所以小心病毒和黑客Q不但用Y件方面的安全{略Q你更需要一个健全的理制度。此外,量的让你的数据攑֜不同的地方,q做好定期(每日Q每周,每月Q的备䆾{略?/p> <p>9. <strong>设计要够灵zR?/strong> 可能你的需求只会要求你实现一个死的东西,但是Q你作ؓ一个优U的程序,你应该随时在思考这个死的东西是否可以有灉|的一面,比如把一些参数变成可以配|的Q把一些公用的东西形成你的函数库以便以后重用,是否提供插g斚w的功能?你的模块是否要以像积木一样随意组合?如果要有修改的话Q你的设计是否能够马上应付?当然Q灵zȝ设计可能q不是要你去重新发明轮子Q你应该可能是使用标准化的东西。所谓灵话的设计是要让让考虑更多需求之外的东西Q把需求中q一cȝ问题都考虑刎ͼ而不是只处理需求中所说的那一特定的东ѝ比如说Q需要需要的屏幕分L率是800×600Q那么你的设计能否灵zM其他的分辨率Q程序设计L需要我们去处理不同的环境,以及未来的趋ѝ我们需要用动态的眼光L考问题,而不是刻舟求剑。也许有一天,你今天写的程序就要移植到别的环境中去Q那个时候你p真正明白什么是灉|的设计了?/p> <p>10. <strong>不要搬v矛_砸自q脚?/strong>E序员L有一U不好的?fn)惯Q那是L惌快地完成自己手上的工作。但情况却往往事已愿违。越是想做得快,p是容易出问题Q越是想做得快,p是容易遗漏问题,最l,E序改过来改q去Q按下葫芦v了瓢Q最后花费的旉和精力反而更多。欲速而不达。优UE序员的?fn)惯是前面多׃些时间多作一些调查,试验一下不同的解决Ҏ(gu)Q如果时间允许,一个好的习(fn)惯是Q每4个小时的~程Q需要一个小时的休息Q然后又?个小时的~码。当Ӟq因异Q但其目的就是让你时常回头看看,让你想一惌样三个问题:1Q是否这么做是对的?2Q是否这么做考虑C所有的情况Q?Q是否有更好的方法?惛_了再_时常回头看看走过的\Q时常ȝ一下过MQ会对你有很大的帮助?/p> <img src ="http://www.tkk7.com/dunkbird/aggbug/308197.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/dunkbird/" target="_blank">大鸟</a> 2010-01-04 18:06 <a href="http://www.tkk7.com/dunkbird/articles/308197.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DOM 解析XMLhttp://www.tkk7.com/dunkbird/articles/307344.html大鸟大鸟Sat, 26 Dec 2009 03:08:00 GMThttp://www.tkk7.com/dunkbird/articles/307344.htmlhttp://www.tkk7.com/dunkbird/comments/307344.htmlhttp://www.tkk7.com/dunkbird/articles/307344.html#Feedback0http://www.tkk7.com/dunkbird/comments/commentRss/307344.htmlhttp://www.tkk7.com/dunkbird/services/trackbacks/307344.htmlpackage demo.xml;

//作?sunchengjun
//旉 2006q?1??/font>
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class DOMParsePage {

public DOMParsePage() {
DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();
try {
     DocumentBuilder dombuilder=domfac.newDocumentBuilder();
InputStream is=new FileInputStream(
"C:/123.xml");
Document doc=dombuilder.parse(is);
Element root=doc.getDocumentElement();
NodeList books=root.getChildNodes();
if(books!=null){
for(int i=0;i<books.getLength();i++){
Node book=books.item(i);
     for(Node node=book.getFirstChild();node!=null;node=node.getNextSibling())
             {
if(node.getNodeType()==Node.ELEMENT_NODE){  

if(node.getNodeName().equals(
"title")){
     String bookname=node.getFirstChild().getNodeValue();
     System.out.println(bookname);
        }

         if(node.getNodeName().equals(
"author")){
     String author1=node.getFirstChild().getNodeValue();
     System.out.println(author1);
               }
         
  if(node.getNodeName().equals(
"description")){
        String addtime=node.getFirstChild().getNodeValue();
        System.out.println(addtime);
       }
  
        if(node.getNodeName().equals(
"pubDate")){
        String price=node.getFirstChild().getNodeValue();
        System.out.println(price);
        }   
     }
    }
    }


}

}
catch (ParserConfigurationException e) {
   e.printStackTrace();
}
     catch (FileNotFoundException e) {
   e.printStackTrace();
}
catch (SAXException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}


}


public static void main(String[] args) {
    new DOMParsePage();
}

}


大鸟 2009-12-26 11:08 发表评论
]]>
jboss 4.2.2 只能localhost讉K 不能通过ip讉K解决http://www.tkk7.com/dunkbird/articles/296730.html大鸟大鸟Mon, 28 Sep 2009 02:02:00 GMThttp://www.tkk7.com/dunkbird/articles/296730.htmlhttp://www.tkk7.com/dunkbird/comments/296730.htmlhttp://www.tkk7.com/dunkbird/articles/296730.html#Feedback0http://www.tkk7.com/dunkbird/comments/commentRss/296730.htmlhttp://www.tkk7.com/dunkbird/services/trackbacks/296730.htmlJBOSS版本Q?.2GA

症状Q服务器无法通过IP地址去访问,只能?27.0.0.1或者localhost来访问?/p>

解决办法Q?/p>

cmd q入dos 到bin?输入 run -b 192.168.50.39


启动JBOSS的时候输入:run -b xxx.xxx.xxx.xxx
其中xxx.xxx.xxx.xxx为本机的IP地址?/p>

原因Q?br style="line-height: normal" />          JBOSS 4.2以上版本服务启动如果不加M参数的话,只监?27.0.0.1,是说只能用127.0.0.1或者localhost讉KQ用本机的对外地址讉K不了Q同一|络内别的机子没法访问。除非你用参?b ip地址 来绑定监听的地址才可以?br style="line-height: normal" />         q和以前版本的JBOSS不一P以前版本的不加Q何参数是监听本机所有的IP地址Q现在必M用参?b 0.0.0.0才可以监听全部地址?br style="line-height: normal" /> -----------------------引用自:http://hi.baidu.com/iMake

Ҏ(gu)2Q?br style="line-height: normal" /> 修改 jboss-4.2.0.GA\server\default\deploy\jboss-web.deployer\server.xml ?Connector 下面?address Ҏ(gu)对应?IP 或?0.0.0.0 可以用 IP 讉K了?/span>

 

JBOSS版本Q?.2.2GA
症状Q服务器无法通过IP地址去访问,只能?27.0.0.1或者localhost来访问?br style="line-height: normal" /> 解决办法Q?br style="line-height: normal" /> 启动JBOSS的时候输入:run -b xxx.xxx.xxx.xxx
其中xxx.xxx.xxx.xxx为本机的IP地址?br style="line-height: normal" /> 原因Q?br style="line-height: normal" /> JBOSS 4.2以上版本服务启动如果不加M参数的话,只监?27.0.0.1,是说只能用127.0.0.1或者localhost讉KQ用本机的对外地址讉K不了Q同一|络内别的机子没法访问。除非你用参?b ip地址 来绑定监听的地址才可以?br style="line-height: normal" /> q和以前版本的JBOSS不一P以前版本的不加Q何参数是监听本机所有的IP地址Q现在必M用参?b 0.0.0.0才可以监听全部地址?br style="line-height: normal" />
======================================
附,以下是我的具体解x法:
在jboss-4.2.2.GA\bin目录下,新徏start.bat文gQ录入如下内容:
run.bat -b 0.0.0.0
保存卛_。用你新制作的start.bat文g启动服务之后可以IP讉K了?br style="line-height: normal" />



大鸟 2009-09-28 10:02 发表评论
]]>
ActiveMQ入门(?http://www.tkk7.com/dunkbird/articles/295286.html大鸟大鸟Wed, 16 Sep 2009 05:00:00 GMThttp://www.tkk7.com/dunkbird/articles/295286.htmlhttp://www.tkk7.com/dunkbird/comments/295286.htmlhttp://www.tkk7.com/dunkbird/articles/295286.html#Feedback0http://www.tkk7.com/dunkbird/comments/commentRss/295286.htmlhttp://www.tkk7.com/dunkbird/services/trackbacks/295286.html1、环境:
Windows XP
apache-activemq-5.2.0-bin.zip
 
2、安?/div>
解压~到apache-activemq-5.2.0-bin.zipC个目录,比如C:\apache-activemq-5.2.0
 
3、配|?/div>
配置在C:\apache-activemq-5.2.0\conf目录下三个文?/div>
activemq.xml
credentials.properties
log4j.properties
 
4、启动ActiveMQ
q行C:\apache-activemq-5.2.0\bin\activemq.bat
5、测?/div>
ActiveMQ默认使用的TCPq接端口?1616, 通过查看该端口的信息可以试ActiveMQ是否成功启动 netstat -an|find "61616"

C:\Documents and Settings\Administrator>netstat -an|find "61616"
    TCP        0.0.0.0:61616                    0.0.0.0:0                            LISTENING
6、监?/div>
ActiveMQ5.0版本默认启动Ӟ启动了内|的jetty服务器,提供一个demo应用和用于监控ActiveMQ的admin应用?br /> adminQ?a >http://127.0.0.1:8161/admin/
demoQ?a >http://127.0.0.1:8161/demo/

下面是ActiveMQ5.2的一个最单例子!
环境q是apache-activemq-5.2.0-bin.zipQ需要注意的是,开发时候,要将apache-activemq- 5.2.0-bin.zip解压~后里面的activemq-all-5.2.0.jar包加入到classpath下面Q这个包包含了所有jms接口 api的实现?/div>

Java代码 复制代码
  1. import org.apache.activemq.ActiveMQConnection;   
  2. import org.apache.activemq.ActiveMQConnectionFactory;   
  3.   
  4. import javax.jms.*;   
  5.   
  6. /**  
  7. * 消息的生产者(发送者)  
  8. *  
  9. */  
  10. public class JmsSender {   
  11.         public static void main(String[] args) throws JMSException {   
  12.                 // ConnectionFactory Q连接工厂,JMS 用它创徏q接   
  13.                 ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(   
  14.                                 ActiveMQConnection.DEFAULT_USER,   
  15.                                 ActiveMQConnection.DEFAULT_PASSWORD,   
  16.                                 "tcp://192.168.14.117:61616");   
  17.                 //JMS 客户端到JMS Provider 的连?  
  18.                 Connection connection = connectionFactory.createConnection();   
  19.                 connection.start();   
  20.                 // SessionQ?nbsp;一个发送或接收消息的线E?  
  21.                 Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);   
  22.                 // Destination Q消息的目的?消息发送给?   
  23.                 // 获取session注意参数值my-queue是Query的名?  
  24.                 Destination destination = session.createQueue("my-queue");   
  25.                 // MessageProducerQ消息生产?  
  26.                 MessageProducer producer = session.createProducer(destination);   
  27.                 //讄不持久化   
  28.                 producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);   
  29.                 //发送一条消?  
  30.                 sendMsg(session, producer);   
  31.                 session.commit();   
  32.                 connection.close();   
  33.         }   
  34.   
  35.         /**  
  36.          * 在指定的会话上,通过指定的消息生产者发Z条消? 
  37.          *  
  38.          * @param session    消息会话  
  39.          * @param producer 消息生? 
  40.          */  
  41.         public static void sendMsg(Session session, MessageProducer producer) throws JMSException {   
  42.                 //创徏一条文本消?  
  43.                 TextMessage message = session.createTextMessage("Hello ActiveMQQ?);   
  44.                 //通过消息生者发出消?  
  45.                 producer.send(message);   
  46.                 System.out.println("");   
  47.         }   
  48. }  
 
Java代码 复制代码
  1. import org.apache.activemq.ActiveMQConnection;   
  2. import org.apache.activemq.ActiveMQConnectionFactory;   
  3.   
  4. import javax.jms.*;   
  5.   
  6. /**  
  7. * 消息的消费者(接受者)  
  8. *  
  9. */  
  10. public class JmsReceiver {   
  11.         public static void main(String[] args) throws JMSException {   
  12.                 // ConnectionFactory Q连接工厂,JMS 用它创徏q接   
  13.                 ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(   
  14.                                 ActiveMQConnection.DEFAULT_USER,   
  15.                                 ActiveMQConnection.DEFAULT_PASSWORD,   
  16.                                 "tcp://192.168.14.117:61616");   
  17.                 //JMS 客户端到JMS Provider 的连?  
  18.                 Connection connection = connectionFactory.createConnection();   
  19.                 connection.start();   
  20.                 // SessionQ?nbsp;一个发送或接收消息的线E?  
  21.                 Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);   
  22.                 // Destination Q消息的目的?消息发送给?   
  23.                 // 获取session注意参数值xingbo.xu-queue是一个服务器的queueQ须在在ActiveMq的console配置   
  24.                 Destination destination = session.createQueue("my-queue");   
  25.                 // 消费者,消息接收?  
  26.                 MessageConsumer consumer = session.createConsumer(destination);   
  27.                 while (true) {   
  28.                         TextMessage message = (TextMessage) consumer.receive(1000);   
  29.                         if (null != message)   
  30.                                 System.out.println("收到消息Q? + message.getText());   
  31.                         else  
  32.                                 break;   
  33.                 }   
  34.                 session.close();   
  35.                 connection.close();   
  36.         }   
  37. }  
 
启动ActiveMQQ然后开始执行:
先运行发送者,q箋q行了三ơ,最后一ơ控制台输出Q?/div>


Process finished with exit code 0
 
后运行接受者,输出l果Q?/div>
收到消息Hello ActiveMQQ?
收到消息Hello ActiveMQQ?
收到消息Hello ActiveMQQ?

Process finished with exit code 0
 
注意Q?/div>
其中的端?1616是ActiveMQ默认的配|,在activemq.xml中,

Xml代码 复制代码
  1. <!-- The transport connectors ActiveMQ will listen to -->  
  2.              <transportConnectors>  
  3.                      <transportConnector name="openwire" uri="tcp://localhost:61616" discoveryUri="multicast://default"/>  
  4.                      <transportConnector name="ssl" uri="ssl://localhost:61617"/>  
  5.                      <transportConnector name="stomp" uri="stomp://localhost:61613"/>  
  6.                      <transportConnector name="xmpp" uri="xmpp://localhost:61222"/>  
  7.              </transportConnectors>   
 
Q徏议不要改动,都用q个端口多好Q就像ftp都用21端口Q也没错?/div>
 
 
q是官方的HelloWorld例子Q不q看着不顺|



大鸟 2009-09-16 13:00 发表评论
]]>JBoss和JMS(写的不错Q抄来看?http://www.tkk7.com/dunkbird/articles/295055.html大鸟大鸟Mon, 14 Sep 2009 11:34:00 GMThttp://www.tkk7.com/dunkbird/articles/295055.htmlhttp://www.tkk7.com/dunkbird/comments/295055.htmlhttp://www.tkk7.com/dunkbird/articles/295055.html#Feedback0http://www.tkk7.com/dunkbird/comments/commentRss/295055.htmlhttp://www.tkk7.com/dunkbird/services/trackbacks/295055.html1、介l?br />       本章介绍在Jboss中用Java Messageing Service (JMS). 不是JMS指南Q而是JBoss和JMS如何一起用,如果你想看JMS的介l,请参?JMS Specification ?JMS turorial.
最q随着JBoss版本不断更新Q对JMS支持来成熟,也造成JBoss各个版本之间的不同。在q里我主要介lJBoss3.0.X版本?br />       本章l出的例子比较简单,q指Z如何使用JMS的原理。所有的例子可以通过ant build file 来徏立?br /> Z能徏立和q行此例子。我们用两U方式来q行Q一是用Ant命oQ二是用JAR和JAVA基本命o。必L下面的环境变量:
        JAVA_HOME 安装JDK1.4的目录?br />         JBOSS_DIST 安装JBoss的目录?br /> 你必d装JDK, 如果使用Ant必须安装 Ant。可以参考我前面文档的介l?/p>

2、概q?br />      1Q?什么是JMS
      JMS是Java API, 允许应用E序来徏立、接收和d消息。程序依靠这些API, 在运行时需要一个JMS实现接口Q来提供理和控Ӟq被UCؓJMS provider, 现在有几U不同的JMS Provider; 在JBoss中的叫做JbossMQ?br />       2Q?JMS 和J2EE
     JMS是在EJB和J2EE框架开发之前进行开发的Q所以在JMS说明书中没有涉及到EJB或J2EE?br /> EJB 和J2EEW一代版本中也没有涉及到JMSQ一直到EJB1.1Q在生成一个可用Beand的容器provider中JMS也不是必ȝAPI。在J2EE1.2中JMS接口是必需的情况,但ƈ不是非得要包含一个JMS ProviderQ在EJB2.0和J2EE1.3中又q行改变Q应用服务器包含了一个JMS ProviderQ自从J2EE1?需要EJB2.0Q增加了以下两个JMSҎ(gu):
w 一U新Beancd定义Q?也就是消息驱动Beam (MDB), q种bean做ؓJMS消息监听者,可以异步地处理JMS消息?br /> w JMS处理作ؓ资源Q来自一个Bean 的JMD 发布Q发送)必须能和其他bean的全局事务环境׃n。这个需要把JMS认ؓ是一个容器管理资源,象JDBC的连接?br />     3Q?JMS 和JBoss
    JBoss?.0版本以后都支持JMS??.1中增加了MDBQ从2.4版本开始JMS作ؓ一个事务资源?br /> JBoss中JMS的体pȝ构如下:JMS Provider, 叫做JbossMQ ?是JBoss实现JMS 1.0.2规范的一部分Q包括可选部分,象ASFQApplication Service FacvilityQ?JbossMQ处理和普遍JMS一P建立 queues (队列)或topic(标题)Q持久性等?MDB (Message Driven Beans), 资源适配器?br /> 3、JMS Provider
      JBoss有它自己的JMS Provider 叫做JbossMQ?适合与JMS 1.0.2 的JMS ProviderQƈ且能用在所有^常的JMSE序中。ؓ了清楚在JBoss中JMS是如何工作的Q首先要清楚在JMS中涉及到的概念和术语Q最好的办法是阅读JMS规范Q下面给Z单的JMS介绍?br />     1) JMS的简单介l?br />      当你发送一个消息,你不能直接发送到Ҏ(gu)消息感兴的接受者。而是你发送到一个目的地。对此消息感兴趣的接受者必连接到目的圎ͼ得到此消息或在目的地讄订阅?br /> 在JMS中有两种域:topics 和queues 。一个消息发送到一个topics Q可以有多个客户端。用topic发布允许一对多Q或多对多通讯通道。消息的产生者被叫做publisher, 消息接受者叫做subscriber?br /> queue 是另外一U方式,仅仅允许一个消息传送给一个客戗一个发送者将消息攑֜消息队列中,接受者从队列中抽取ƈ得到消息Q消息就会在队列中消失。第一个接受者抽取ƈ得到消息后,其他人就不能在得到它?br /> Z能发送和接收消息Q必dC个JMSq接。该q接是用JMS Provider得到q接的,在得到连接之后,建立一个会?Session)。然后再建立publisher/sender 来发送消息或subscriber/receiver来接收消息?br /> q行Ӟ如果使用topic 那么publisher 或subscriber 通过一个topic来关联,如果使用queue Q则sender 或receiver通过queue来关联v来?br /> 通常Q在JMS框架中运转的Ҏ(gu)如下Q?br /> (1) 得到一个JNDI初始化上下文(Context)Q?br /> (2) Ҏ(gu)上下文来查找一个连接工厂TopicConnectFactory/ QueueConnectionFactory (有两U连接工厂,Ҏ(gu)是topic/queue来用相应的cd)Q?br /> (3) 从连接工厂得C个连?Connect 有两U[TopicConnection/ QueueConnection]);
(4) 通过q接来徏立一个会?Session);
(5) 查找目的?Topic/ Queue);
(6) Ҏ(gu)会话以及目的地来建立消息刉?TopicPublisher/QueueSender)和消费?TopicSubscriber/ QueueReceiver).
Z得到一个连接和得到一个目的地Q用来关联publisher/sender 或subscriber/receiverQ,必须用provider-specific参数?br /> 通过JNDI来查扄应的q接工厂或目的地QJNDI适合于Q何JMS Provider。但是查扄的名字是provider使用的。因此,在你使用的JMS ProviderQ其中包括JBossMQQ,必须学会如何q行指定。JMS Provider中的M讄Q象q接Ҏ(gu),用到目的地等Q在用到的Provider都有明确描述?br /> 2) 配置
当用一个JMS ProviderӞ有三个Provider-specific因素Q?br /> w 得到一个JNDI初始化上下文
w 用到的连接工厂的名字?br /> w 对目的地的管理和命名协定?br /> JBoss同它的JNDI一h行。ؓ了简单的JMS clientQ?配置和查扑ֈ始化上下文,同实现其他J2EE客户端一栗?br /> JMS-specific 来约束JBoss 的JMS provider (JBossMQ)。JbossMQ是通过xml 文gjbossmq-service.xmlq行配置的,该文件放在在server\default\deploy下?br /> 在xml文g中最基本的三件事情:
w 增加一个新的目的地
w 配置用户
w 获得可用q接工厂的名字?br /> (1) 增加新的目的?br /> w 在目的地的xml文g在jboss 3.x中是jbossmq-destinations-service.xmlQserver/../deployQ。在文g中已l存在几个缺省的目的圎ͼ所以你比较Ҏ(gu)明白怎样增加到文件中。在例子中你需要一个topic目的?spoolQ所以增加下面的语句到jbossmq-destinations-service.xml中。这U方式是长久存在的,不随着JBoss服务器关闭而消失?br /> <mbean code="org.jboss.mq.server.jmx.Topic"
name="jboss.mq.destination:service=Topic,name=spool">
<depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
</mbean>
w 另外一U方法是可以通过JMX HTML理界面。通过http://localhost:8080/jmx-console 来访问。在jboss.mq 下查找service=DestinationManager 的连接。然后在createTopic()或createQueue()来徏立,q种Ҏ(gu)建立的目的地是(f)时性的Q随着服务器开始存在,当当JBoss 服务器重新启动时Q动态徏立的目的地将会不存在。在JbossMQ中所有目的地都有一个目的地cd的前~。对于topic前缀是topic ,对于queues前缀是queue。例如查找一个testTopic目的圎ͼ需要查扑֐字ؓ“topic/testTopic”?br /> 在此U方法中有createTopic()或createQueue()分别有两U方法:一是有两个参数Q二是有一个参数的。两个参数分别是Q徏立的目的地名U和JNDI名称。一个参数的只是目的地名Uͼ对于JNDI名称默认是:[目的地类?topic/queue) ]/目的地名U?br /> 在这里我们用的是第一U方法。直接修改jbossmq-destinations-service.xml文g?br /> (2) 理用户
在JMS中可能关联一个连接和一个用P不幸的是没有明确的方法来限制讉KJbossMQ或访问特D的目的地到一个给定的用户。ؓ了给大部分角Ԍ在JbossMQ中不需要徏立用P除非x一个持久topic订阅者。在q个例子中,用户是必ȝ?br /> 用户可以直接在文件jbossmq-state.xmlQserver/../confQ中d。同样也可以使用JMX HTML理界面来增加(jboss.mq->service=StateManager->addUser()Q?br /> <User>
<Name>jacky</Name>
<Password>jacky</Password>
<Id>DurableSubscriberExample</Id>
</User>>

(3) q接工厂
JBossMQ 包括为topic和queue几个不同的连接工厂,每个q接工厂有自q性。当通过JNDI来查找一个连接工厂时Q需要知道此q接工厂的名U。所有可用连接工厂和它们的属性,名称都会在文件jbossmq-service.xml中?br /> 有三U类型连接工厂,依赖的通讯协议如下Q?br /> OIL
快速双向scoket通讯协议。它是缺省的?br /> UIL
过一个socket协议Q可以用在通过防火墙访问,或者当客户端不能正的查找到服务器的IP地址?br /> RMI
最早的协议Q是E_的,但是比较慢?br /> JVM
在JBoss 2.4之后增加的一个新的连接工厂类型。不需要用socketQ当客户端和JbossMQ使用同样虚拟机时Q可以用?br /> 在JBoss2.4.1以后版本中,对于topic- ?queue-目的圎ͼq接工厂使用同样的名字。下表列Z在JBoss中JMSq接工厂Q?br /> 目的地类?JNDI名字 q接工厂cd
Topic/Queue java:/ConnectionFactory JVM
Topic/Queue java:/XAConnectionFactory JVM支持XA事务
Topic/Queue RMIConnectionFactory RMI
Topic/Queue RMIXAConnectionFactory RMI支持XA事务
Topic/Queue ConnectionFactory OIL
Topic/Queue XAConnectionFactory OIL支持XA事务
Topic/Queue UILConnectionFactory UIL
Topic/Queue UILXAConnectionFactory UIL支持XA事务

3Q?JBoss中高UJMS配置
在上Ҏ(gu)落主要描qC和JbossMQ一起实行的基本配置工作。在本段来描qJMS其他配置?br /> (1) JMS持久性管?br /> JMS持久性管?PM)负责存储消息Qƈ且将消息标记为持久,如果服务器发生故障时Q能保证消息不会丢失Qƈ允许恢复持久性消息。持久性JMS消息可以使用不同的方法来完成。每个方法有自己优点和缺P
PM 名字 优点 ~点
File 比较E_ 速度?br /> Rollinglogged 速度比较?此方法比较新Q有些地斚w要完?br /> JDBC 对于E_性和可量性比较好 必须有JDBC
Logged 速度?Log files grow without bound, memory management problems during recovery
在JBoss中缺省的持久性消息管理是File持久性管理。可以改变它Q但必须对于一个JMS
Server有且仅有一个持久性管理配|。所以你在JBoss理界面的jboss.mq – >
service=PersistenceManager 只是看到一个?br /> 持久性管理的配置文g是jbossmq-service.xml。在server\..\deploy下?br /> Z让大家了解持久性管理的各种Ҏ(gu)Q我下面来逐个介绍如何配置?br /> w File持久性管?br /> File持久性管理的概念是为每一个持久性消息徏立一个文件。消息持久性方法不是全部都能用,但它是比较稳定的?br /> File持久性管理在JBoss发布Ӟ作ؓ一个缺省的持久性管理。如果你打开jbossmq-service.xml文gQ你会看C面的XMLQ?br /> <mbean code="org.jboss.mq.pm.file.PersistenceManager"
name="jboss.mq:service=PersistenceManager">
<attribute >db/jbossmq/file</attribute>
<depends optional-attribute-name="MessageCache">jboss.mq:service=MessageCache</depends>
</mbean>
当设|Mbean配置ӞFile持久性管理允怽指定下面的属性:
DataDircetory 是存放持久性消息的路径Q会把生成的数据文g攑֜此目录下?/p>

w 讄Rollinglogged持久性管?br /> Rollinglogged持久性管理是比较新的一U持久性消息管理方法,因ؓ它用日志文件来持箋多个消息Q所以当建立一个文件时Q不需要许多的I/O?br /> 定义Rollinglogged持久性管理:
<mbean code="org.jboss.mq.pm.rollinglogged.PersistenceManager"
name="jboss.mq:service=PersistenceManager">
<attribute >db/jbossmq/file</attribute>
<depends optional-attribute-name="MessageCache">jboss.mq:service=MessageCache</depends>
</mbean>
Rollinglogged持久性管理中DataDirctory 存放持久性消息的路径Q会把生成的数据文g攑֜此目录下?/p>

w 讄JDBC持久性管?br /> JDBC持久性管理用数据库表来存储消息。需要一个JBoss配置的数据源来访问数据库。具体内容参考jbossmq-service.xml文g中的内容?br /> w 讄Logged持久性管?br /> Logged持久性管理是比较早的一个,在JBoss2.4.1以后版本中不在徏议用。现在有其他更好的办法?br /> 4、D例说?br /> 当我们清楚了以后内容后,现在我们来用JBoss实现一个例子来加深对JBoss和JMS的了解?br /> 在上面叙qCQ我们知道明用JMS provider有三个基本的事情要做Q配|JNDI初始化上下文Q连接工厂的名字和用目的地的名字?br /> 当编写品的最好的事情是不受provider-specific 影响Q代码能在不同的JMS provider之间Ҏ(gu)UL。在此这个例子没有聚焦在开发品上Q而是解释如何使用JbossMQ来工作?br /> 1) 初始化上下文
w 配置JNDI的一个方法是通过属性文件jndi.properties。在q个文g中用正的|q且把它所在的路径包含到classpath中,它比较容获得正确初始化上下文?br /> jndi.properties文g的内容如下:
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=localhost:1099
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
把该文g攄的\径成Z的classpath的一部分。如果你使用q种Ҏ(gu)Q在初始化上下文Ӟ代码比较? Context context = new IntialContext();1
w 在某些情景下Q可能需要手工配|JNDIQ例如当q行的类文g中环境已l配|了一个初始化上下文,但不是你想用的上下文Ӟ需要手工来配置一个上下文。设|在哈希表中的几个属性|q且使用此哈希表来实例化一个上下文。定义语法:
Hashtable props = new Hashtable();
props.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jnp.interfaces.NamingContextFactory");
props.put(Context.PROVIDER_URL, "localhost:1099");
props.put("java.naming.rmi.security.manager", "yes");
props.put(Context.URL_PKG_PREFIXES, "org.jboss.naming");

2) 查找q接工厂
自有了上下文后,需要查找一个连接工厂。ؓ了查扑֮Q用一个可用的名字。查找连接工厂的代码如下Q?br /> 对于一个topic目的?br /> TopicConnectionFactory topicFactory = (TopicConnectionFactory) context.lookup (“ConnectionFactory”)
Queue 目的圎ͼ
QueueConnectionFactory queueFactory = (QueueConnectionFactory ) context.lookup (“ConnectionFactory”)
3) 建立q接和会?br /> 在我们有了连接工厂后Q徏立一个连接,在此q接中徏立一个会话?br /> 对于topic代码如下Q?br /> //建立一个连?br /> topicConnection = topicFactory.createTopicConnection();
//建立一个会?br /> topicSession = topicConnection.createTopicSession(false, //不需要事?br /> Session.AUTO_ACKNOLEDGE //自动接收消息的收条?br /> );
对于queue代码如下Q?br /> //建立一个连?br /> queueConnection = queueFactory.createQueueConnection();
//建立一个会?br /> queueSession = queueConnection .createQueueSession(false, //不需要事?br /> Session.AUTO_ACKNOLEDGE //自动接收消息的收条?br /> );
一个会话徏立时Q配|是否调用事?br /> 在事务Session中,当事务被提交后,自动接收Q如果事务回滚,所有的被消费的消息会被重新发送?br /> 在非事务Session中,如果没有调用事务处理Q消息传递的方式有三U:
Session.AUTO_ACKNOWLEDGE :当客h调用的receiveҎ(gu)成功q回Q或当MessageListenser 成功处理了消息,session会自动接收消息的收条?br /> Session.CLIENT_ACKNOWLEDGE Q客h通过调用消息的acknowledgeҎ(gu)来接收消息。接收发生在session层。接收到一个被消费的消息时Q将自动接收该session已经消费的所有消息。例如:如果消息的消费者消费了10条消息,然后接收15个被传递的消息Q则前面?0个消息的收据都会在这15个消息中被接收?br /> Session.DUPS_ACKNOWLEDGE Q指Csession~慢接收消息?/p>

4) 查找目的?br /> 现在我们来介l徏立publishes/sends 或subscribles/receives消息?br /> 下面的代码列出来查找一个目的地Q?br /> 对于topic 查找一个testTopic目的?br /> Topic topic = (Topic) context.lookup(“topic/testTopic”);

对于queue 查找一个testQueue目的?br /> Queue queue= (Queue) context.lookup(“queue/testQueue”);
注意QJbossM的前~topic/ (queue/)通常被放在topic (queue)名字前面?br /> 在JMS中,当客h扮演每种角色Q象对于topic来将的publisher ,subscriber 或对于queue来将的sender, receiverQ?都有自己不同cȝ承和不同函数?br /> 5) 建立一个消息制造者Message Producer (topic publisher/ queue sender)
消息刉者是一个由session创徏的对象,主要工作是发送消息到目的地?br /> 对于一个topicQ需要通过TopicSession来创Z个TopicPublisher。代码如下:
TopicPublisher topicPublisher = TopicSession.createPublisher(topic);

对于一个queueQ需要通过QueueSession来创Z个QueueSender。代码如下:
QueuePublisher queuePublisher = queueSession.createSender(queue);
6) 消息发?br /> 建立一个TestMessageq且publish 它, 代码Q?br /> TextMessage message = topicSession.createTestMessage();
message.setText(msg);
topicPublishe.publish(topic, message);
建立一个TestMessageq且send它, 代码Q?br /> TextMessage message = queueSession.createTestMessage();
message.setText(msg);
queueSender.send(queue, message);

7) 下面是一个完成的topic publisher 代码Q文件名HelloPublisher.java Q?br /> import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.jms.TopicConnectionFactory;
import javax.jms.TopicConnection;
import javax.jms.TopicSession;
import javax.jms.TopicPublisher;
import javax.jms.Topic;
import javax.jms.TextMessage;
import javax.jms.Session;
import javax.jms.JMSException;
import java.util.Hashtable;
public class HelloPublisher {

TopicConnection topicConnection;
TopicSession topicSession;
TopicPublisher topicPublisher;
Topic topic;

public HelloPublisher(String factoryJNDI, String topicJNDI)
throws JMSException, NamingException {
Hashtable props=new Hashtable();
props.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
props.put(Context.PROVIDER_URL, "localhost:1099");
props.put("java.naming.rmi.security.manager", "yes");
props.put(Context.URL_PKG_PREFIXES, "org.jboss.naming");
Context context = new InitialContext(props);
TopicConnectionFactory topicFactory =
(TopicConnectionFactory)context.lookup(factoryJNDI);
topicConnection = topicFactory.createTopicConnection();
topicSession = topicConnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);

topic = (Topic)context.lookup(topicJNDI);

topicPublisher = topicSession.createPublisher(topic);

}

public void publish(String msg) throws JMSException {

TextMessage message = topicSession.createTextMessage();
message.setText(msg);
topicPublisher.publish(topic, message);
}

public void close() throws JMSException {
topicSession.close();
topicConnection.close();
}

public static void main(String[] args) {
try {
HelloPublisher publisher = new HelloPublisher(
"ConnectionFactory", "topic/testTopic");
for (int i = 1; i < 11; i++) {
String msg = "Hello World no. " + i;
System.out.println("Publishing message: " + msg);
publisher.publish(msg);
}
publisher.close();
} catch(Exception ex) {
System.err.println(
"An exception occurred while testing HelloPublisher25: " + ex);
ex.printStackTrace();
}
}
}
我们知道Q用JMS不仅能发送(sendQ?发布QpublishQ消息,也能获得QsendQ?发布QpublishQ的消息。在旉方式有良U方法来做:
w 同步QSynchronouslyQ:需要手工的d到消息,Z得到一个消息客h调用Ҏ(gu)得到消息Q直到消息到达或在规定的旉内没有到达而超时。我们在例子中没有说明这部分Q大家可以实验一下?br /> w 异步QAsynchronouslyQ:你需要定义一个消息监听器(MessageListener),实现该接口。当消息辑ֈӞJMS provider通过调用该对象的 onMessageҎ(gu)来传递消息?br /> 从原则来,topic和queue都是异步的,但是在这两种目的C有不同的cdҎ(gu)。首先,必须定义一个MessageListener接口?
8) 建立一个MessageListener
在徏立了你需要的subscriber/receiverQƈ且登C监听器后。就可以调用q接的startҎ(gu)得到JMS provider 发送到的消息了。如果在登记监听器之前调用startҎ(gu)Q很可能会丢失消息?br /> public void onMessage(Message m) {
try {
String msg = ((TextMessage)m).getText();
System.out.println("HelloSubscriber got message: " + msg);
} catch(JMSException ex) {
System.err.println("Could not get text message: " + ex);
ex.printStackTrace();
}
}
9) 建立消息消费?br /> 对于topic来将Q?br /> //建立一个订阅?br /> topicSubscriber = topicSession.createSubscriber(topic);
//讄消息监听器,
topicSubscriber.setMessageListener(this)
//q接开?br /> topicConnection.start();
对于queue来将Q?br /> //建立一个订阅?br /> queueReceiver = queueSession.createReceiver(queue);
//讄消息监听器,
queueReceiver .setMessageListener(this)
//q接开?br /> queueConnection.start();
10) 完整的代码,攑֜文gHelloSubscriber.java中,如下Q?br /> import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import javax.jms.TopicConnectionFactory;
import javax.jms.TopicConnection;
import javax.jms.TopicSession;
import javax.jms.TopicSubscriber;
import javax.jms.Topic;
import javax.jms.Message;
import javax.jms.TextMessage;
import javax.jms.Session;
import javax.jms.MessageListener;
import javax.jms.JMSException;

public class HelloSubscriber implements MessageListener {
TopicConnection topicConnection;
TopicSession topicSession;
TopicSubscriber topicSubscriber;
Topic topic;
public HelloSubscriber(String factoryJNDI, String topicJNDI)
throws JMSException, NamingException
{
Context context = new InitialContext();
TopicConnectionFactory topicFactory =
(TopicConnectionFactory)context.lookup(factoryJNDI);
topicConnection = topicFactory.createTopicConnection();
topicSession = topicConnection.createTopicSession(
false, Session.AUTO_ACKNOWLEDGE);
topic = (Topic)context.lookup(topicJNDI);
topicSubscriber = topicSession.createSubscriber(topic);
topicSubscriber.setMessageListener(this);
System.out.println(
"HelloSubscriber subscribed to topic: " + topicJNDI);
topicConnection.start();
}
public void onMessage(Message m) {
try {
String msg = ((TextMessage)m).getText();
System.out.println("HelloSubscriber got message: " + msg);
} catch(JMSException ex) {
System.err.println("Could not get text message: " + ex);
ex.printStackTrace();
}
}
public void close() throws JMSException {
topicSession.close();
topicConnection.close();
}
public static void main(String[] args) {
try {
HelloSubscriber subscriber = new HelloSubscriber(
"TopicConnectionFactory",
"topic/testTopic");
} catch(Exception ex) {
System.err.println(
"An exception occurred while testing HelloSubscriber: " + ex);
ex.printStackTrace();
}
}
}

11) ~辑、运行程?br /> 直接使用命oQjavaQ?
w 开启命令操作符。设|classpath :
set classpath=C:\jboss-3.0.6_tomcat-4.1.18\client\jbossall-client.jar;C:\jboss-3.0.6_tomcat-4.1.18\client\jboss-j2ee.jar;C:\jboss-3.0.6_tomcat-4.1.18\client\jnp-client.jar;C:\jboss-3.0.6_tomcat-4.1.18\client\log4j.jar;.
w 首先q行订阅消息端:java HelloSubscriber
w 再开启另外一个命令窗口设|classpath :
set classpath=C:\jboss-3.0.6_tomcat-4.1.18\client\jbossall-client.jar;C:\jboss-3.0.6_tomcat-4.1.18\client\jboss-j2ee.jar;C:\jboss-3.0.6_tomcat-4.1.18\client\jnp-client.jar;C:\jboss-3.0.6_tomcat-4.1.18\client\log4j.jar;.
w q行发布消息端:java HelloPublisher
5、补?br /> 在最后我们解释JBoss-specificҎ(gu):如何用代码来理目的地。JBoss各个版本可能不同Q但是差别不大。我使用的是jboss3.0.6?br /> 实现q个目的有两U不同的Ҏ(gu)Q依赖于是否代码是在和JBoss同样的虚拟机q是独立独立的。它们都包括调用一个通过service=DestinationManager 登记的JMX Bean。这个Mbean 有四个方法来理目的圎ͼcreateTopic()QcreateQueue()QdestroyTopic()QdestroyQueue()?br /> 在代码中实现理目的地在影射怎样调用MBean有不同的地方。如果程序虚拟机和Mbean服务器一P可以直接调用?br /> 建立一个topic 目的地的代码如下Q?br /> MBeanServer server = (MBeanServer)
MBeanServerFactory.findMBeanServer(null).iterator().next();
server.invoke(new ObjectName("JBossMQ", "service", "DestinationManager"),
method,
new Object[] { “myTopic” },
new String[] { "java.lang.String" });

如果E序和Mbean服务器的虚拟Z同,需要通过一个JMX adapter。一个JMX adapter是一个HTML GUI。用E序通过URL来调用Mbean。代码如下:
import java.io.InputStream;
import java.net.URL;
import java.net.HttpURLConnection;
import javax.management.MBeanServerFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.jms.Topic;
import javax.jms.Queue;
public class DestinationHelper {
static final String HOST = "localhost";
static final int PORT = 8080;
static final String BASE_URL_ARG = "/jmx-console/HtmlAdaptor?";
public static void createDestination(Class type, String name)
throws Exception
{
String method = null;
if (type == Topic.class) { method = "createTopic"; }
else if (type == Queue.class) { method = "createQueue";}
invoke(method, name);
}

public static void destroyDestination(Class type, String name)
throws Exception
{
String method = null;
if (type == Topic.class) { method = "destroyTopic"; }
else if (type == Queue.class) { method = "destroyQueue";}
invoke(method, name);
}

protected static void invoke(String method, String destName)
throws Exception
{
try {
MBeanServer server = (MBeanServer) MBeanServerFactory.findMBeanServer(null).iterator().next();
invokeViaMBean(method, destName);
}catch(Exception ex) { invokeViaUrl(method, destName);}
}
protected static void invokeViaUrl(String method, String destName)
throws Exception
{
String action = "action=invokeOp&methodIndex=6&name=jboss.mq%3Aservice%3DDestinationManager&arg0=" + destName;
String arg = BASE_URL_ARG + action;
URL url = new URL("http", HOST, PORT, arg);
HttpURLConnection con = (HttpURLConnection)url.openConnection();
con.connect();

InputStream is = con.getInputStream();
java.io.ByteArrayOutputStream os = new java.io.ByteArrayOutputStream();
byte[] buff = new byte[1024];
for(;;) {
int size = is.read( buff );
if (size == -1 ) { break; }
os.write(buff, 0, size);
}
os.flush();

if (con.getResponseCode() != HttpURLConnection.HTTP_OK ) {
throw new Exception ("Could not invoke url: " + con.getResponseMessage() );
} else {
System.out.println("Invoked URL: " + method + " for destination " + destName + "got resonse: " + os.toString());
}
}
protected static void invokeViaMBean(String method, String destName)
throws Exception
{
MBeanServer server = (MBeanServer)MBeanServerFactory.findMBeanServer(null).iterator().next();
server.invoke(new ObjectName("JBossMQ", "service", "DestinationManager"),
method,
new Object[] { destName },
new String[] { "java.lang.String" });
}
public static void main(String[] args) {
try {
if (args.length >0){
destroyDestination(Topic.class,"myCreated");
}else {
createDestination(Topic.class,"myCreated");
}
}catch(Exception ex) {
System.out.println("Error in administering destination: " + ex);
ex.printStackTrace();
}
}

}
~辑命oQ?br /> javac -classpath C:\jboss-3.0.6_tomcat-4.1.18\client\jbossall-client.jar;C:\jboss-3.0.6_tomcat-4.1.18\lib\jboss-jmx.jar;. DestinationHelper.java
q行命o
java -classpath C:\jboss-3.0.6_tomcat-4.1.18\client\jbossall-client.jar;C:\jboss-3.0.6_tomcat-4.1.18\lib\jboss-jmx.jar;. DestinationHelper
当运行完后查?a href="http://localhost:8080/jmx-console">http://localhost:8080/jmx-console下面的jboss.mq.destination中有name=myCreated,service=Topic
表明你徏立成功。当JBoss关闭重新启动时。该目的C会在存在?/p>

大鸟 2009-09-14 19:34 发表评论
]]>
java concurrent 探秘Q?Q?/title><link>http://www.tkk7.com/dunkbird/articles/295038.html</link><dc:creator>大鸟</dc:creator><author>大鸟</author><pubDate>Mon, 14 Sep 2009 09:07:00 GMT</pubDate><guid>http://www.tkk7.com/dunkbird/articles/295038.html</guid><wfw:comment>http://www.tkk7.com/dunkbird/comments/295038.html</wfw:comment><comments>http://www.tkk7.com/dunkbird/articles/295038.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/dunkbird/comments/commentRss/295038.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/dunkbird/services/trackbacks/295038.html</trackback:ping><description><![CDATA[<p><font size="4">BlockingQueue</font><br /> 支持两个附加操作?QueueQ这两个操作是:索元素时{待队列变ؓ非空Q以及存储元素时{待I间变得可用?/p> <p>BlockingQueue 不接?null 元素。试?add、put ?offer 一?null 元素Ӟ某些实现会抛?NullPointerException。null 被用作指C?poll 操作p|的警戒倹{?/p> <p>BlockingQueue 可以是限定容量的。它在Q意给定时间都可以有一?remainingCapacityQ超出此定wQ便无法无阻塞地 put 额外的元素?br /> 没有M内部定wU束?BlockingQueue L报告 Integer.MAX_VALUE 的剩余容量?/p> <p>BlockingQueue 实现主要用于生?使用者队列,但它另外q支?Collection 接口。因此,举例来说Q?remove(x) 从队列中U除L一个元素是有可能的?br /> 然而,q种操作通常?会有效执行,只能有计划地偶尔使用Q比如在取消排队信息时?/p> <p>BlockingQueue 实现是线E安全的。所有排队方法都可以使用内部锁定或其他Ş式的q发控制来自动达到它们的目的?br /> 然而,大量?Collection 操作QaddAll、containsAll、retainAll ?removeAllQ没?必要自动执行Q除非在实现中特别说明?br /> 因此QD例来_在只d?c 中的一些元素后QaddAll(c) 有可能失败(抛出一个异常)?/p> <p>BlockingQueue 实质上不 支持使用M一U?#8220;close”?#8220;shutdown”操作来指CZ再添加Q何项?br /> q种功能的需求和使用有依赖于实现的們֐。例如,一U常用的{略是:对于生者,插入Ҏ(gu)?end-of-stream ?poison 对象QƈҎ(gu)使用者获取这些对象的旉来对它们q行解释?/p> <p>下面的例子演CZq个d队列的基本功能?/p> <p><font color="#0000ff">import java.util.concurrent.BlockingQueue;<br /> import java.util.concurrent.ExecutorService;<br /> import java.util.concurrent.Executors;<br /> import java.util.concurrent.LinkedBlockingQueue;</font></p> <p><font color="#0000ff">public class MyBlockingQueue extends Thread {<br /> public static BlockingQueue<String> queue = new LinkedBlockingQueue<String>(3);</font></p> <p><font color="#0000ff">private int index;</font></p> <p><font color="#0000ff">public MyBlockingQueue(int i) {<br />    this.index = i;<br /> }</font></p> <p><font color="#0000ff">public void run() {<br />    try {<br />     queue.put(String.valueOf(this.index));<br />     System.out.println("{" + this.index + "} in queue!");<br />    } catch (Exception e) {<br />     e.printStackTrace();<br />    }<br /> }</font></p> <p><font color="#0000ff">public static void main(String args[]) {<br />    ExecutorService service = Executors.newCachedThreadPool();<br />    for (int i = 0; i < 10; i++) {<br />     service.submit(new MyBlockingQueue(i));<br />    }<br />    Thread thread = new Thread() {<br />     public void run() {<br />      try {<br />       while (true) {<br />        Thread.sleep((int) (Math.random() * 1000));<br />        if(MyBlockingQueue.queue.isEmpty())<br />         break;<br />        String str = MyBlockingQueue.queue.take();<br />        System.out.println(str + " has take!");<br />       }<br />      } catch (Exception e) {<br />       e.printStackTrace();<br />      }<br />     }<br />    };<br />    service.submit(thread);<br />    service.shutdown();<br /> }<br /> }<br /> </font>---------------------执行l果-----------------<br /> <font color="#ff0000">{0} in queue!<br /> {1} in queue!<br /> {2} in queue!<br /> {3} in queue!<br /> 0 has take!<br /> {4} in queue!<br /> 1 has take!<br /> {6} in queue!<br /> 2 has take!<br /> {7} in queue!<br /> 3 has take!<br /> {8} in queue!<br /> 4 has take!<br /> {5} in queue!<br /> 6 has take!<br /> {9} in queue!<br /> 7 has take!<br /> 8 has take!<br /> 5 has take!<br /> 9 has take!</font></p> <p>-----------------------------------------</p> <p><br /> <font size="4">CompletionService</font></p> <p>生产新的异步Q务与使用已完成Q务的l果分离开来的服务。生产?submit 执行的Q务。用?take 已完成的dQ?br /> q按照完成这些Q务的序处理它们的结果。例如,CompletionService 可以用来理异步 IO Q执行读操作的Q务作为程序或pȝ的一部分提交Q?br /> 然后Q当完成L作时Q会在程序的不同部分执行其他操作Q执行操作的序可能与所h的顺序不同?/p> <p>通常QCompletionService 依赖于一个单独的 Executor 来实际执行Q务,在这U情况下Q?br /> CompletionService 只管理一个内部完成队列。ExecutorCompletionService cL供了此方法的一个实现?/p> <p><br /> <font color="#0000ff">import java.util.concurrent.Callable;<br /> import java.util.concurrent.CompletionService;<br /> import java.util.concurrent.ExecutorCompletionService;<br /> import java.util.concurrent.ExecutorService;<br /> import java.util.concurrent.Executors;</font></p> <p><font color="#0000ff">public class MyCompletionService implements Callable<String> {<br /> private int id;<br /> <br /> public MyCompletionService(int i){<br />    this.id=i;<br /> }<br /> public static void main(String[] args) throws Exception{<br />    ExecutorService service=Executors.newCachedThreadPool();<br />    CompletionService<String> completion=new ExecutorCompletionService<String>(service);<br />    for(int i=0;i<10;i++){<br />     completion.submit(new MyCompletionService(i));<br />    }<br />    for(int i=0;i<10;i++){<br />     System.out.println(completion.take().get());<br />    }<br />    service.shutdown();<br /> }<br /> public String call() throws Exception {<br />    Integer time=(int)(Math.random()*1000);<br />    try{<br />     System.out.println(this.id+" start");<br />     Thread.sleep(time);<br />     System.out.println(this.id+" end");<br />    }<br />    catch(Exception e){<br />     e.printStackTrace();<br />    }<br />    return this.id+":"+time;<br /> }<br /> }</font></p> <p><br /> <font size="4">CountDownLatch</font></p> <p><br /> 一个同步辅助类Q在完成一l正在其他线E中执行的操作之前,它允怸个或多个U程一直等待?/p> <p>用给定的计数 初始?CountDownLatch。由于调用了 countDown() Ҏ(gu)Q所以在当前计数到达零之前,await Ҏ(gu)会一直受d?br /> 之后Q会释放所有等待的U程Qawait 的所有后l调用都立卌回。这U现象只出现一ơ——计数无法被重置。如果需要重|计敎ͼ误虑使用 CyclicBarrier?/p> <p>CountDownLatch 是一个通用同步工具Q它有很多用途。将计数 1 初始化的 CountDownLatch 用作一个简单的开/关锁存器Q?br /> 或入口:在通过调用 countDown() 的线E打开入口前,所有调?await 的线E都一直在入口处等待?br /> ?N 初始化的 CountDownLatch 可以使一个线E在 N 个线E完成某Ҏ(gu)作之前一直等待,或者其在某项操作完成 N ơ之前一直等待?/p> <p>CountDownLatch 的一个有用特性是Q它不要求调?countDown Ҏ(gu)的线E等到计数到N时才l箋Q?br /> 而在所有线E都能通过之前Q它只是LMU程l箋通过一?await?<br /> 一下的例子是别人写的,非常形象?/p> <p><font color="#0000ff">import java.util.concurrent.CountDownLatch;<br /> import java.util.concurrent.ExecutorService;<br /> import java.util.concurrent.Executors;</font></p> <p><font color="#0000ff">public class TestCountDownLatch {<br /> public static void main(String[] args) throws InterruptedException {<br />    // 开始的倒数?br />    final CountDownLatch begin = new CountDownLatch(1);<br />    // l束的倒数?br />    final CountDownLatch end = new CountDownLatch(10);<br />    // 十名选手<br />    final ExecutorService exec = Executors.newFixedThreadPool(10);<br />   <br />    for (int index = 0; index < 10; index++) {<br />     final int NO = index + 1;<br />     Runnable run = new Runnable() {<br />      public void run() {<br />       try {<br />        begin.await();//一直阻?br />        Thread.sleep((long) (Math.random() * 10000));<br />        System.out.println("No." + NO + " arrived");<br />       } catch (InterruptedException e) {<br />       } finally {<br />        end.countDown();<br />       }<br />      }<br />     };<br />     exec.submit(run);<br />    }<br />    System.out.println("Game Start");<br />    begin.countDown();<br />    end.await();<br />    System.out.println("Game Over");<br />    exec.shutdown();<br /> }<br /> }<br /> </font>CountDownLatch最重要的方法是countDown()和await()Q前者主要是倒数一ơ,后者是{待倒数?Q如果没有到?Q就只有d{待了?/p> <p><br /> <font size="4">CyclicBarrier</font></p> <p>一个同步辅助类Q它允许一l线E互相等待,直到到达某个公共屏障?(common barrier point)?br /> 在涉及一l固定大的U程的程序中Q这些线E必M时地互相{待Q此?CyclicBarrier 很有用。因 barrier 在释攄待线E后可以重用Q所以称它ؓ循环 ?barrier?/p> <p>CyclicBarrier 支持一个可选的 Runnable 命oQ在一l线E中的最后一个线E到达之后(但在释放所有线E之前)Q?br /> 该命令只在每个屏障点q行一ơ。若在l所有参与线E之前更新共享状态,此屏障操?很有用?/p> <p>CZ用法Q下面是一个在q行分解设计中?barrier 的例子,很经典的旅行团例子:<br /> <font color="#0000ff">import java.text.SimpleDateFormat;<br /> import java.util.Date;<br /> import java.util.concurrent.BrokenBarrierException;<br /> import java.util.concurrent.CyclicBarrier;<br /> import java.util.concurrent.ExecutorService;<br /> import java.util.concurrent.Executors;<br /> public class TestCyclicBarrier {<br /> // 徒步需要的旉: Shenzhen, Guangzhou, Shaoguan, Changsha, Wuhan<br /> private static int[] timeWalk = { 5, 8, 15, 15, 10 };<br /> // 自驾?br /> private static int[] timeSelf = { 1, 3, 4, 4, 5 };<br /> // 旅游大巴<br /> private static int[] timeBus = { 2, 4, 6, 6, 7 };<br /> <br /> static String now() {<br />     SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");<br />     return sdf.format(new Date()) + ": ";<br /> }</font></p> <p><font color="#0000ff">static class Tour implements Runnable {<br />     private int[] times;<br />     private CyclicBarrier barrier;<br />     private String tourName;<br />     public Tour(CyclicBarrier barrier, String tourName, int[] times) {<br />       this.times = times;<br />       this.tourName = tourName;<br />       this.barrier = barrier;<br />     }<br />     public void run() {<br />       try {<br />         Thread.sleep(times[0] * 1000);<br />         System.out.println(now() + tourName + " Reached Shenzhen");<br />         barrier.await();<br />         Thread.sleep(times[1] * 1000);<br />         System.out.println(now() + tourName + " Reached Guangzhou");<br />         barrier.await();<br />         Thread.sleep(times[2] * 1000);<br />         System.out.println(now() + tourName + " Reached Shaoguan");<br />         barrier.await();<br />         Thread.sleep(times[3] * 1000);<br />         System.out.println(now() + tourName + " Reached Changsha");<br />         barrier.await();<br />         Thread.sleep(times[4] * 1000);<br />         System.out.println(now() + tourName + " Reached Wuhan");<br />         barrier.await();<br />       } catch (InterruptedException e) {<br />       } catch (BrokenBarrierException e) {<br />       }<br />     }<br /> }</font></p> <p><font color="#0000ff">public static void main(String[] args) {<br />     // 三个旅行?br />     CyclicBarrier barrier = new CyclicBarrier(3);<br />     ExecutorService exec = Executors.newFixedThreadPool(3);<br />     exec.submit(new Tour(barrier, "WalkTour", timeWalk));<br />     exec.submit(new Tour(barrier, "SelfTour", timeSelf));<br /> //当我们把下面的这D代码注释后Q会发现Q程序阻塞了Q无法l运行下厅R?br />     exec.submit(new Tour(barrier, "BusTour", timeBus));<br />     exec.shutdown();<br /> }<br /> } </font></p> <p>CyclicBarrier最重要的属性就是参与者个敎ͼ另外最要方法是await()。当所有线E都调用了await()后,pC些线E都可以l箋执行Q否则就会等待?/p> <p><font size="4">Future</font></p> <p>Future 表示异步计算的结果。它提供了检查计是否完成的Ҏ(gu)Q以{待计算的完成,q检索计的l果?br /> 计算完成后只能?get Ҏ(gu)来检索结果,如有必要Q计完成前可以d此方法。取消则?cancel Ҏ(gu)来执行?br /> q提供了其他Ҏ(gu)Q以定d是正常完成还是被取消了。一旦计完成,׃能再取消计算?br /> 如果Z可取消性而?Future但又不提供可用的l果Q则可以声明 Future<?> 形式cd、ƈq回 null 作ؓ基础d的结果?/p> <p>q个我们在前面CompletionService已经看到了,q个Future的功能,而且q个可以在提交线E的时候被指定Z个返回对象的?/p> <p><br /> <font size="4">ScheduledExecutorService</font></p> <p>一?ExecutorServiceQ可安排在给定的延迟后运行或定期执行的命令?/p> <p>schedule Ҏ(gu)使用各种延迟创徏dQƈq回一个可用于取消或检查执行的d对象。scheduleAtFixedRate ?scheduleWithFixedDelay Ҏ(gu)创徏q执行某些在取消前一直定期运行的d?/p> <p>?Executor.execute(java.lang.Runnable) ?ExecutorService ?submit Ҏ(gu)所提交的命令,通过所h?0 延迟q行安排?br /> schedule Ҏ(gu)中允许出?0 和负数gq(但不是周期)Qƈ这些视ZU立x行的h?/p> <p>所有的 schedule Ҏ(gu)都接受相?延迟和周期作为参敎ͼ而不是绝对的旉或日期。将?Date 所表示的绝Ҏ(gu)间{换成要求的Ş式很Ҏ(gu)?br /> 例如Q要安排在某个以后的日期q行Q可以用:schedule(task, date.getTime() - System.currentTimeMillis(), TimeUnit.MILLISECONDS)?br /> 但是要注意,׃|络旉同步协议、时钟漂UL其他因素的存在,因此相对延迟的期满日期不必与启用d的当?Date 相符?br /> Executors cMؓ此包中所提供?ScheduledExecutorService 实现提供了便L(fng)工厂Ҏ(gu)?/p> <p>一下的例子也是|上比较行的?/p> <p><font color="#0000ff">import static java.util.concurrent.TimeUnit.SECONDS;<br /> import java.util.Date;<br /> import java.util.concurrent.Executors;<br /> import java.util.concurrent.ScheduledExecutorService;<br /> import java.util.concurrent.ScheduledFuture;</font></p> <p><font color="#0000ff">public class TestScheduledThread {<br /> public static void main(String[] args) {<br />    final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);<br />    final Runnable beeper = new Runnable() {<br />     int count = 0;</font></p> <p><font color="#0000ff">    public void run() {<br />      System.out.println(new Date() + " beep " + (++count));<br />     }<br />    };<br />    // 1U钟后运行,q每?U运行一?br />    final ScheduledFuture beeperHandle = scheduler.scheduleAtFixedRate(beeper, 1, 2, SECONDS);<br />    // 2U钟后运行,q每ơ在上次dq行完后{待5U后重新q行<br />    final ScheduledFuture beeperHandle2 = scheduler.scheduleWithFixedDelay(beeper, 2, 5, SECONDS);<br />    // 30U后l束关闭dQƈ且关闭Scheduler<br />    scheduler.schedule(new Runnable() {<br />     public void run() {<br />      beeperHandle.cancel(true);<br />      beeperHandle2.cancel(true);<br />      scheduler.shutdown();<br />     }<br />    }, 30, SECONDS);<br /> }<br /> }</font></p> <p>q样我们把concurrent包下比较重要的功能都已经ȝ完了Q希望对我们理解能有帮助?/p> <img src ="http://www.tkk7.com/dunkbird/aggbug/295038.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/dunkbird/" target="_blank">大鸟</a> 2009-09-14 17:07 <a href="http://www.tkk7.com/dunkbird/articles/295038.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java concurrent 探秘Q?Q?/title><link>http://www.tkk7.com/dunkbird/articles/295037.html</link><dc:creator>大鸟</dc:creator><author>大鸟</author><pubDate>Mon, 14 Sep 2009 09:06:00 GMT</pubDate><guid>http://www.tkk7.com/dunkbird/articles/295037.html</guid><wfw:comment>http://www.tkk7.com/dunkbird/comments/295037.html</wfw:comment><comments>http://www.tkk7.com/dunkbird/articles/295037.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/dunkbird/comments/commentRss/295037.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/dunkbird/services/trackbacks/295037.html</trackback:ping><description><![CDATA[ 我们都知道,在JDK1.5之前QJava中要q行业务q发Ӟ通常需要有E序员独立完成代码实玎ͼ当然也有一些开源的框架提供了这些功能,但是q些依然没有JDK自带的功能用v来方ѝ而当针对高质量Java多线Eƈ发程序设计时,为防止死y等现象的出玎ͼ比如使用java之前的wait()、notify()和synchronized{,每每需要考虑性能、死锁、公qx、资源管理以及如何避免线E安全性方面带来的危害{诸多因素,往往会采用一些较为复杂的安全{略Q加重了E序员的开发负?万幸的是Q在JDK1.5出现之后QSun大神QDoug LeaQ终于ؓ我们q些可怜的程序员推出了java.util.concurrent工具包以化ƈ发完成。开发者们借助于此Q将有效的减竞争条Ӟrace conditionsQ和死锁U程。concurrent包很好的解决了这些问题,为我们提供了更实用的q发E序模型? <p><br /> Executor                 Q具体Runnabled的执行者?br /> ExecutorService          Q一个线E池理者,其实现类有多U,我会介绍一部分。我们能把Runnable,Callable提交到池中让其调度?br /> Semaphore                Q一个计C号量<br /> ReentrantLock            Q一个可重入的互斥锁?LockQ功能类似synchronizedQ但要强大的多?br /> Future                   Q是与Runnable,Callableq行交互的接口,比如一个线E执行结束后取返回的l果{等Q还提供了cancell止U程?br /> BlockingQueue            Q阻塞队列?br /> CompletionService        : ExecutorService的扩展,可以获得U程执行l果?br /> CountDownLatch           Q一个同步辅助类Q在完成一l正在其他线E中执行的操作之前,它允怸个或多个U程一直等待?<br /> CyclicBarrier            Q一个同步辅助类Q它允许一l线E互相等待,直到到达某个公共屏障?<br /> Future                   QFuture 表示异步计算的结果?br /> ScheduledExecutorService Q一?ExecutorServiceQ可安排在给定的延迟后运行或定期执行的命令?/p> <p>接下来逐一介绍</p> <p><font size="4">Executors主要Ҏ(gu)说明<br /> </font><strong><font size="2">newFixedThreadPool</font>Q?/strong>固定大小U程池)<br /> 创徏一个可重用固定U程集合的线E池Q以׃n的无界队列方式来q行q些U程Q只有要h的过来,׃在一个队列里{待执行Q。如果在关闭前的执行期间׃p|而导致Q何线E终止,那么一个新U程代替它执行后箋的Q务(如果需要)?/p> <p><strong>newCachedThreadPool</strong>Q无界线E池Q可以进行自动线E回Ӟ<br /> 创徏一个可Ҏ(gu)需要创建新U程的线E池Q但是在以前构造的U程可用时将重用它们。对于执行很多短期异步Q务的E序而言Q这些线E池通常可提高程序性能。调?execute 重用以前构造的U程Q如果线E可用)。如果现有线E没有可用的Q则创徏一个新U程q添加到池中。终止ƈ从缓存中U除那些已有 60 U钟未被使用的线E。因此,长时间保持空闲的U程池不会用Q何资源。注意,可以使用 ThreadPoolExecutor 构造方法创建具有类似属性但l节不同Q例如超时参敎ͼ的线E池?/p> <p><strong>newSingleThreadExecutor</strong>Q单个后台线E)<br /> 创徏一个用单?worker U程?ExecutorQ以无界队列方式来运行该U程。(注意Q如果因为在关闭前的执行期间出现p|而终止了此单个线E,那么如果需要,一个新U程代替它执行后箋的Q务)。可保证序地执行各个Q务,q且在Q意给定的旉不会有多个线E是zd的。与其他{效?newFixedThreadPool(1) 不同Q可保证无需重新配置此方法所q回的执行程序即可用其他的U程?/p> <p>q些Ҏ(gu)q回的都是ExecutorService对象Q这个对象可以理解ؓ是一个线E池?br /> q个U程池的功能q是比较完善的。可以提交Q务submit()可以l束U程池shutdown()?/p> <p><font color="#0000ff">import java.util.concurrent.ExecutorService;<br /> import java.util.concurrent.Executors;</font></p> <p><font color="#0000ff">public class MyExecutor extends Thread {<br /> private int index;<br /> public MyExecutor(int i){<br />    this.index=i;<br /> }<br /> public void run(){<br />    try{<br />     System.out.println("["+this.index+"] start....");<br />     Thread.sleep((int)(Math.random()*1000));<br />     System.out.println("["+this.index+"] end.");<br />    }<br />    catch(Exception e){<br />     e.printStackTrace();<br />    }<br /> }<br /> <br /> public static void main(String args[]){<br />    ExecutorService service=Executors.newFixedThreadPool(4);<br />    for(int i=0;i<10;i++){<br />     service.execute(new MyExecutor(i));<br />     //service.submit(new MyExecutor(i));<br />    }<br />    System.out.println("submit finish");<br />    service.shutdown();<br /> }<br /> }</font></p> <p>虽然打印了一些信息,但是看的不是非常清晰Q这个线E池是如何工作的Q我们来休眠的旉调长10倍?br /> Thread.sleep((int)(Math.random()*10000));</p> <p>再来看,会清楚看到只能执?个线E。当执行完一个线E后Q才会又执行一个新的线E,也就是说Q我们将所有的U程提交后,U程池会{待执行完最后shutdown。我们也会发玎ͼ提交的线E被攑ֈ一?#8220;无界队列?#8221;。这是一个有序队列(BlockingQueueQ这个下面会说到Q?/p> <p>另外它用了Executors的静态函数生成一个固定的U程池,֐思义Q线E池的线E是不会释放的,即它是Idle?br /> q就会生性能问题Q比如如果线E池的大ؓ200Q当全部使用完毕后,所有的U程会l留在池中,相应的内存和U程切换Qwhile(true)+sleep循环Q都会增加?br /> 如果要避免这个问题,必ȝ接用ThreadPoolExecutor()来构造。可以像通用的线E池一栯|?#8220;最大线E数”?#8220;最线E数”?#8220;I闲U程keepAlive的时?#8221;?/p> <p><br /> q个是U程池基本用法?br /> <br /> <font size="4">Semaphore</font><br /> 一个计C号量。从概念上讲Q信号量l护了一个许可集合。如有必要,在许可可用前会阻塞每一?acquire()Q然后再获取该许可。每?release() d一个许可,从而可能释放一个正在阻塞的获取者。但是,不用实际的许可对象QSemaphore 只对可用许可的号码进行计敎ͼq取相应的行动?/p> <p>Semaphore 通常用于限制可以讉K某些资源Q物理或逻辑的)的线E数目。例如,下面的类使用信号量控制对内容池的讉KQ?/p> <p>q里是一个实际的情况Q大家排队上厕所Q厕所只有两个位置Q来?0个h需要排队?/p> <p><font color="#0000ff">import java.util.concurrent.ExecutorService;<br /> import java.util.concurrent.Executors;<br /> import java.util.concurrent.Semaphore;</font></p> <p><font color="#0000ff">public class MySemaphore extends Thread {<br /> Semaphore position;<br /> private int id;<br /> public MySemaphore(int i,Semaphore s){<br />    this.id=i;<br />    this.position=s;<br /> }<br /> <br /> public void run(){<br />    try{<br />     if(position.availablePermits()>0){<br />      System.out.println("֮["+this.id+"]q入厕所Q有IZ");<br />     }<br />     else{<br />      System.out.println("֮["+this.id+"]q入厕所Q没IZQ排?);<br />     }<br />     position.acquire();<br />     System.out.println("֮["+this.id+"]获得坑位");<br />     Thread.sleep((int)(Math.random()*1000));<br />     System.out.println("֮["+this.id+"]使用完毕");<br />     position.release();<br />    }<br />    catch(Exception e){<br />     e.printStackTrace();<br />    }<br /> }<br /> public static void main(String args[]){<br />    ExecutorService list=Executors.newCachedThreadPool();<br />    Semaphore position=new Semaphore(2);<br />    for(int i=0;i<10;i++){<br />     list.submit(new MySemaphore(i+1,position));<br />    }<br />    list.shutdown();<br />    position.acquireUninterruptibly(2);<br />    System.out.println("使用完毕Q需要清扫了");<br />    position.release(2);<br /> }<br /> }</font></p> <p> </p> <p><font size="4">ReentrantLock</font><br /> 一个可重入的互斥锁?LockQ它h与?synchronized Ҏ(gu)和语句所讉K的隐式监视器锁定相同的一些基本行为和语义Q但功能更强大?/p> <p>ReentrantLock 由最q成功获得锁定,q且q没有释放该锁定的线E所拥有。当锁定没有被另一个线E所拥有Ӟ调用 lock 的线E将成功获取该锁定ƈq回。如果当前线E已l拥有该锁定Q此Ҏ(gu)立卌回。可以?isHeldByCurrentThread() ?getHoldCount() Ҏ(gu)来检查此情况是否发生?/p> <p>此类的构造方法接受一个可选的公^参数?br /> 当设|ؓ trueӞ在多个线E的争用下,q些锁定們֐于将讉K权授予等待时间最长的U程。否则此锁定无法保证Q何特定访问顺序?br /> 与采用默认设|(使用不公q锁定)相比Q用公q锁定的E序在许多线E访问时表现为很低的M吞吐量(即速度很慢Q常常极其慢Q,但是在获得锁定和保证锁定分配的均衡性时差异较小。不q要注意的是Q公q锁定不能保证线E调度的公^性。因此,使用公^锁定的众多线E中的一员可能获得多倍的成功ZQ这U情况发生在其他zdU程没有被处理ƈ且目前ƈ未持有锁定时。还要注意的是,未定时的 tryLock Ҏ(gu)q没有用公q|。因为即使其他线E正在等待,只要该锁定是可用的,此方法就可以获得成功?/p> <p>L 立即实践Q?try 块来调用 lockQ在之前/之后的构造中Q最典型的代码如下: <br /> class X {<br />    private final ReentrantLock lock = new ReentrantLock();<br />    // ...</p> <p>   public void m() { <br />      lock.lock(); // block until condition holds<br />      try {<br />        // ... method body<br />      } finally {<br />        lock.unlock()<br />      }<br />    }<br /> }</p> <p>我的例子Q?br /> <font color="#0000ff">import java.util.concurrent.ExecutorService;<br /> import java.util.concurrent.Executors;<br /> import java.util.concurrent.locks.ReentrantLock;</font></p> <p><font color="#0000ff">public class MyReentrantLock extends Thread{<br /> TestReentrantLock lock;<br /> private int id;<br /> public MyReentrantLock(int i,TestReentrantLock test){<br />    this.id=i;<br />    this.lock=test;<br /> }<br /> <br /> public void run(){<br />    lock.print(id);<br /> }</font></p> <p><font color="#0000ff">public static void main(String args[]){<br />    ExecutorService service=Executors.newCachedThreadPool();<br />    TestReentrantLock lock=new TestReentrantLock();<br />    for(int i=0;i<10;i++){<br />     service.submit(new MyReentrantLock(i,lock));<br />    }<br />    service.shutdown();<br /> }<br /> }<br /> class TestReentrantLock{<br /> private ReentrantLock lock=new ReentrantLock();<br /> public void print(int str){<br />    try{<br />     lock.lock();<br />     System.out.println(str+"获得");<br />     Thread.sleep((int)(Math.random()*1000));<br />    }<br />    catch(Exception e){<br />     e.printStackTrace();<br />    }<br />    finally{<br />     System.out.println(str+"释放");<br />     lock.unlock();<br />    }<br /> }<br /> }</font></p> <img src ="http://www.tkk7.com/dunkbird/aggbug/295037.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/dunkbird/" target="_blank">大鸟</a> 2009-09-14 17:06 <a href="http://www.tkk7.com/dunkbird/articles/295037.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java U程池的原理与实?/title><link>http://www.tkk7.com/dunkbird/articles/291429.html</link><dc:creator>大鸟</dc:creator><author>大鸟</author><pubDate>Mon, 17 Aug 2009 01:58:00 GMT</pubDate><guid>http://www.tkk7.com/dunkbird/articles/291429.html</guid><wfw:comment>http://www.tkk7.com/dunkbird/comments/291429.html</wfw:comment><comments>http://www.tkk7.com/dunkbird/articles/291429.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/dunkbird/comments/commentRss/291429.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/dunkbird/services/trackbacks/291429.html</trackback:ping><description><![CDATA[最q在学习(fn)U程池、内存控制等关于提高E序q行性能斚w的编E技术,在网上看到有一哥们写得不错Q故和大家一起分享?br /> <br /> [分n]Java U程池的原理与实?br /> <br /> <br /> q几天主要是狂看源程序,在I补了一些以前知识空白的同时Q也学会了不新的知识(比如 NIOQ,或者称为新技术吧?br /> U程池就是其中之一Q一提到U程Q我们会惛_以前《操作系l》的生者与消费者,信号量,同步控制{等?br /> 一提到池,我们会想到数据库q接池,但是U程池又如何呢?<br /> <br /> <br /> <strong></strong>Q在阅读本文前,先理一理同步的知识Q特别是syncronized同步关键字的用法?br /> 关于我对同步的认识,要缘于大三年的一本书Q书名好像是 Java 实战Q这本书写得实在太妙了,真正的从理论到实践,从截囑ֈ析到.class字节码分析。哇Q我惛_Z很难买到q么_致的书了。作Z个Java爱好者,我觉得绝对值得一诅R?br /> 我对此书印象最׃一的就是:equal()Ҏ(gu)Q由入深,l典Q?br /> q有是同步了,其中提到了我的几个编E误区,以前如何使用同步提高性能{等Q通过学习(fn)Q我对同步的认识进一步加深?br /> <br /> <br /> <font size="3"><strong>单介l?/strong></font><br /> <br />     创徏U程有两U方式:l承Thread或实现Runnable。Thread实现了Runnable接口Q提供了一个空的run()Ҏ(gu)Q所以不论是l承Threadq是实现RunnableQ都要有自己的run()Ҏ(gu)?br />     一个线E创建后存在,调用start()Ҏ(gu)开始运行(执行run()Ҏ(gu)Q,调用waitq入{待或调用sleepq入休眠期,利q行完毕或休眠被中断或运行过E中出现异常而退出?br /> <br /> <strong>wait和sleep比较Q?/strong><br />       sleepҎ(gu)有:sleep(long millis)Qsleep(long millis, long nanos)Q调用sleepҎ(gu)后,当前U程q入休眠期,暂停执行Q但该线El拥有监视资源的所有权。到达休眠时间后U程l执行,直到完成。若在休眠期另一U程中断该线E,则该U程退出?br />       waitҎ(gu)有:wait()Qwait(long timeout)Qwait(long timeout, long nanos)Q调用waitҎ(gu)后,该线E放弃监视资源的所有权q入{待状态;<br />       wait()Q等待有其它的线E调用notify()或notifyAll()q入调度状态,与其它线E共同争夺监视。wait()相当于wait(0)Qwait(0, 0)?br />       wait(long timeout)Q当其它U程调用notify()或notifyAll()Q或旉到达timeout亳秒Q或有其它某U程中断该线E,则该U程q入调度状态?br />       wait(long timeout, long nanos)Q相当于wait(1000000*timeout + nanos)Q只不过旉单位为纳U?br /> <br /> <br /> <br /> <font color="#ff0000" size="3"><strong>U程池:</strong></font><br />     多线E技术主要解军_理器单元内多个线E执行的问题Q它可以显著减少处理器单元的闲置旉Q增加处理器单元的吞吐能力?br />     <br />     假设一个服务器完成一Q务所需旉为:T1 创徏U程旉QT2 在线E中执行d的时_T3 销毁线E时间?br />     <br />     如果QT1 + T3 q大?T2Q则可以采用U程池,以提高服务器性能?br />                 一个线E池包括以下四个基本l成部分Q?br />                 1、线E池理器(ThreadPoolQ:用于创徏q管理线E池Q包?创徏U程池,销毁线E池Q添加新dQ?br />                 2、工作线E(PoolWorkerQ:U程池中U程Q在没有d时处于等待状态,可以循环的执行Q务;<br />                 3、Q务接口(TaskQ:每个d必须实现的接口,以供工作U程调度d的执行,它主要规定了d的入口,d执行完后的收ַ作,d的执行状态等Q?br />                 4、Q务队列(taskQueueQ:用于存放没有处理的Q务。提供一U缓冲机制?br />                 <br />     U程池技术正是关注如何羃短或调整T1,T3旉的技术,从而提高服务器E序性能的。它把T1QT3分别安排在服务器E序的启动和l束的时间段或者一些空闲的旉D,q样在服务器E序处理客户hӞ不会有T1QT3的开销了?br /> <br />     U程池不仅调整T1,T3产生的时间段Q而且它还显著减少了创建线E的数目Q看一个例子:<br /> <br />     假设一个服务器一天要处理50000个请求,q且每个h需要一个单独的U程完成。在U程池中Q线E数一般是固定的,所以生线EL不会过U程池中U程的数目,而如果服务器不利用线E池来处理这些请求则U程L?0000。一般线E池大小是远于50000。所以利用线E池的服务器E序不会Z创徏50000而在处理h时浪Ҏ(gu)_从而提高效率?br /> <br /> <br /> <strong>/** U程池类Q工作线E作为其内部c?**/</strong><br /> <br /> package org.ymcn.util;<br /> <br /> import java.util.Collections;<br /> import java.util.Date;<br /> import java.util.LinkedList;<br /> import java.util.List;<br /> <br /> import org.apache.log4j.Logger;<br /> <br /> /**<br /> * U程?br /> * 创徏U程池,销毁线E池Q添加新d<br /> * <br /> * @author obullxl<br /> */<br /> public final class ThreadPool {<br />     private static Logger logger = Logger.getLogger(ThreadPool.class);<br />     private static Logger taskLogger = Logger.getLogger("TaskLogger");<br /> <br />     private static boolean debug = taskLogger.isDebugEnabled();<br />     // private static boolean debug = taskLogger.isInfoEnabled();<br />     /* 单例 */<br />     private static ThreadPool instance = ThreadPool.getInstance();<br /> <br />     public static final int SYSTEM_BUSY_TASK_COUNT = 150;<br />     /* 默认池中U程?*/<br />     public static int worker_num = 5;<br />     /* 已经处理的Q务数 */<br />     private static int taskCounter = 0;<br /> <br />     public static boolean systemIsBusy = false;<br /> <br />     private static List<Task> taskQueue = Collections<br />             .synchronizedList(new LinkedList<Task>());<br />     /* 池中的所有线E?*/<br />     public PoolWorker[] workers;<br /> <br />     private ThreadPool() {<br />         workers = new PoolWorker[5];<br />         for (int i = 0; i < workers.length; i++) {<br />             workers[i] = new PoolWorker(i);<br />         }<br />     }<br /> <br />     private ThreadPool(int pool_worker_num) {<br />         worker_num = pool_worker_num;<br />         workers = new PoolWorker[worker_num];<br />         for (int i = 0; i < workers.length; i++) {<br />             workers[i] = new PoolWorker(i);<br />         }<br />     }<br /> <br />     public static synchronized ThreadPool getInstance() {<br />         if (instance == null)<br />             return new ThreadPool();<br />         return instance;<br />     }<br />     /**<br />     * 增加新的d<br />     * 每增加一个新dQ都要唤醒Q务队?br />     * @param newTask<br />     */<br />     public void addTask(Task newTask) {<br />         synchronized (taskQueue) {<br />             newTask.setTaskId(++taskCounter);<br />             newTask.setSubmitTime(new Date());<br />             taskQueue.add(newTask);<br />             /* 唤醒队列, 开始执?*/<br />             taskQueue.notifyAll();<br />         }<br />         logger.info("Submit Task<" + newTask.getTaskId() + ">: "<br />                 + newTask.info());<br />     }<br />     /**<br />     * 扚w增加CQ?br />     * @param taskes<br />     */<br />     public void batchAddTask(Task[] taskes) {<br />         if (taskes == null || taskes.length == 0) {<br />             return;<br />         }<br />         synchronized (taskQueue) {<br />             for (int i = 0; i < taskes.length; i++) {<br />                 if (taskes[i] == null) {<br />                     continue;<br />                 }<br />                 taskes[i].setTaskId(++taskCounter);<br />                 taskes[i].setSubmitTime(new Date());<br />                 taskQueue.add(taskes[i]);<br />             }<br />             /* 唤醒队列, 开始执?*/<br />             taskQueue.notifyAll();<br />         }<br />         for (int i = 0; i < taskes.length; i++) {<br />             if (taskes[i] == null) {<br />                 continue;<br />             }<br />             logger.info("Submit Task<" + taskes[i].getTaskId() + ">: "<br />                     + taskes[i].info());<br />         }<br />     }<br />     /**<br />     * U程池信?br />     * @return<br />     */<br />     public String getInfo() {<br />         StringBuffer sb = new StringBuffer();<br />         sb.append("\nTask Queue Size:" + taskQueue.size());<br />         for (int i = 0; i < workers.length; i++) {<br />             sb.append("\nWorker " + i + " is "<br />                     + ((workers[i].isWaiting()) ? "Waiting." : "Running."));<br />         }<br />         return sb.toString();<br />     }<br />     /**<br />     * 销毁线E池<br />     */<br />     public synchronized void destroy() {<br />         for (int i = 0; i < worker_num; i++) {<br />             workers[i].stopWorker();<br />             workers[i] = null;<br />         }<br />         taskQueue.clear();<br />     }<br /> <br />     /**<br />     * 池中工作U程<br />     * <br />     * @author obullxl<br />     */<br />     private class PoolWorker extends Thread {<br />         private int index = -1;<br />         /* 该工作线E是否有?*/<br />         private boolean isRunning = true;<br />         /* 该工作线E是否可以执行新d */<br />         private boolean isWaiting = true;<br /> <br />         public PoolWorker(int index) {<br />             this.index = index;<br />             start();<br />         }<br /> <br />         public void stopWorker() {<br />             this.isRunning = false;<br />         }<br /> <br />         public boolean isWaiting() {<br />             return this.isWaiting;<br />         }<br />         /**<br />         * 循环执行d<br />         * q也许是U程池的关键所?br />         */<br />         public void run() {<br />             while (isRunning) {<br />                 Task r = null;<br />                 synchronized (taskQueue) {<br />                     while (taskQueue.isEmpty()) {<br />                         try {<br />                             /* d队列为空Q则{待有新d加入从而被唤醒 */<br />                             taskQueue.wait(20);<br />                         } catch (InterruptedException ie) {<br />                             logger.error(ie);<br />                         }<br />                     }<br />                     /* 取出d执行 */<br />                     r = (Task) taskQueue.remove(0);<br />                 }<br />                 if (r != null) {<br />                     isWaiting = false;<br />                     try {<br />                         if (debug) {<br />                             r.setBeginExceuteTime(new Date());<br />                             taskLogger.debug("Worker<" + index<br />                                     + "> start execute Task<" + r.getTaskId() + ">");<br />                             if (r.getBeginExceuteTime().getTime()<br />                                     - r.getSubmitTime().getTime() > 1000)<br />                                 taskLogger.debug("longer waiting time. "<br />                                         + r.info() + ",<" + index + ">,time:"<br />                                         + (r.getFinishTime().getTime() - r<br />                                                 .getBeginExceuteTime().getTime()));<br />                         }<br />                         /* 该Q务是否需要立x?*/<br />                         if (r.needExecuteImmediate()) {<br />                             new Thread(r).start();<br />                         } else {<br />                             r.run();<br />                         }<br />                         if (debug) {<br />                             r.setFinishTime(new Date());<br />                             taskLogger.debug("Worker<" + index<br />                                     + "> finish task<" + r.getTaskId() + ">");<br />                             if (r.getFinishTime().getTime()<br />                                     - r.getBeginExceuteTime().getTime() > 1000)<br />                                 taskLogger.debug("longer execution time. "<br />                                         + r.info() + ",<" + index + ">,time:"<br />                                         + (r.getFinishTime().getTime() - r<br />                                                 .getBeginExceuteTime().getTime()));<br />                         }<br />                     } catch (Exception e) {<br />                         e.printStackTrace();<br />                         logger.error(e);<br />                     }<br />                     isWaiting = true;<br />                     r = null;<br />                 }<br />             }<br />         }<br />     }<br /> }<br /> <br /> <strong>/** d接口c?**/</strong><br /> <br /> package org.ymcn.util;<br /> <br /> import java.util.Date;<br /> <br /> /**<br /> * 所有Q务接?br /> * 其他d必须l承访类<br /> * <br /> * @author obullxl<br /> */<br /> public abstract class Task implements Runnable {<br />     // private static Logger logger = Logger.getLogger(Task.class);<br />     /* 产生旉 */<br />     private Date generateTime = null;<br />     /* 提交执行旉 */<br />     private Date submitTime = null;<br />     /* 开始执行时?*/<br />     private Date beginExceuteTime = null;<br />     /* 执行完成旉 */<br />     private Date finishTime = null;<br /> <br />     private long taskId;<br /> <br />     public Task() {<br />         this.generateTime = new Date();<br />     }<br /> <br />     /**<br />     * d执行入口<br />     */<br />     public void run() {<br />         /**<br />         * 相关执行代码<br />         * <br />         * beginTransaction();<br />         * <br />         * 执行q程中可能生新的Q?subtask = taskCore();<br />         * <br />         * commitTransaction();<br />         * <br />         * 增加C生的d ThreadPool.getInstance().batchAddTask(taskCore());<br />         */<br />     }<br /> <br />     /**<br />     * 所有Q务的核心 所以特别的业务逻辑执行之处<br />     * <br />     * @throws Exception<br />     */<br />     public abstract Task[] taskCore() throws Exception;<br /> <br />     /**<br />     * 是否用到数据?br />     * <br />     * @return<br />     */<br />     protected abstract boolean useDb();<br /> <br />     /**<br />     * 是否需要立x?br />     * <br />     * @return<br />     */<br />     protected abstract boolean needExecuteImmediate();<br /> <br />     /**<br />     * d信息<br />     * <br />     * @return String<br />     */<br />     public abstract String info();<br /> <br />     public Date getGenerateTime() {<br />         return generateTime;<br />     }<br /> <br />     public Date getBeginExceuteTime() {<br />         return beginExceuteTime;<br />     }<br /> <br />     public void setBeginExceuteTime(Date beginExceuteTime) {<br />         this.beginExceuteTime = beginExceuteTime;<br />     }<br /> <br />     public Date getFinishTime() {<br />         return finishTime;<br />     }<br /> <br />     public void setFinishTime(Date finishTime) {<br />         this.finishTime = finishTime;<br />     }<br /> <br />     public Date getSubmitTime() {<br />         return submitTime;<br />     }<br /> <br />     public void setSubmitTime(Date submitTime) {<br />         this.submitTime = submitTime;<br />     }<br /> <br />     public long getTaskId() {<br />         return taskId;<br />     }<br /> <br />     public void setTaskId(long taskId) {<br />         this.taskId = taskId;<br />     }<br /> <br /> }<br /> <br /> <br /> <br /> <a >转自Qhttp://hi.baidu.com/obullxl/blog/item/ee50ad1ba8e8ff1f8718bf66.html</a> <img src ="http://www.tkk7.com/dunkbird/aggbug/291429.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/dunkbird/" target="_blank">大鸟</a> 2009-08-17 09:58 <a href="http://www.tkk7.com/dunkbird/articles/291429.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 自带的线E池--转蝲http://www.tkk7.com/dunkbird/articles/291424.html大鸟大鸟Mon, 17 Aug 2009 01:49:00 GMThttp://www.tkk7.com/dunkbird/articles/291424.htmlhttp://www.tkk7.com/dunkbird/comments/291424.htmlhttp://www.tkk7.com/dunkbird/articles/291424.html#Feedback1http://www.tkk7.com/dunkbird/comments/commentRss/291424.htmlhttp://www.tkk7.com/dunkbird/services/trackbacks/291424.html?Java 5 开始,Java 提供了自qU程池。线E池是一个线E的容器Q每ơ只执行额定数量的线E?java.util.concurrent.ThreadPoolExecutor 是q样的线E池。它很灵z,但用v来也比较复杂Q本文就对其做一个介l?/p>

 


首先是构造函数。以最单的构造函Cؓ例:

view plaincopy to clipboardprint?
public ThreadPoolExecutor(  
            int corePoolSize,  
            int maximumPoolSize,  
            long keepAliveTime,  
            TimeUnit unit,  
            BlockingQueue<Runnable> workQueue)
public ThreadPoolExecutor(
            int corePoolSize,
            int maximumPoolSize,
            long keepAliveTime,
            TimeUnit unit,
            BlockingQueue<Runnable> workQueue)

看v来挺复杂的。这里介l一下?/p>

corePoolSize 指的是保留的U程池大?
maximumPoolSize 指的是线E池的最大大?
keepAliveTime 指的是空闲线E结束的时旉?
unit 是一个枚举,表示 keepAliveTime 的单位?
workQueue 表示存放d的队列?/p>

我们可以从线E池的工作过E中了解q些参数的意义。线E池的工作过E如下:

 


1、线E池刚创建时Q里面没有一个线E。Q务队列是作ؓ参数传进来的。不q,q队列里面有Q务,U程池也不会马上执行它们?/p>

2、当调用 execute() Ҏ(gu)d一个Q务时Q线E池会做如下判断Q?/p>

    a. 如果正在q行的线E数量小?corePoolSizeQ那么马上创建线E运行这个Q务;

    b. 如果正在q行的线E数量大于或{于 corePoolSizeQ那么将q个d攑օ队列?/p>

    c. 如果q时候队列满了,而且正在q行的线E数量小?maximumPoolSizeQ那么还是要创徏U程q行q个dQ?/p>

    d. 如果队列满了Q而且正在q行的线E数量大于或{于 maximumPoolSizeQ那么线E池会抛出异常,告诉调用?#8220;我不能再接受d?#8221;?/p>

3、当一个线E完成Q务时Q它会从队列中取下一个Q务来执行?/p>

4、当一个线E无事可做,过一定的旉QkeepAliveTimeQ时Q线E池会判断,如果当前q行的线E数大于 corePoolSizeQ那么这个线E就被停掉。所以线E池的所有Q务完成后Q它最l会收羃?corePoolSize 的大?/p>

q样的过E说明,q不是先加入d׃定会先执行。假N列大ؓ 10QcorePoolSize ?3QmaximumPoolSize ?6Q那么当加入 20 个Q务时Q执行的序是q样的:首先执行d 1??Q然后Q?4~13 被放入队列。这时候队列满了,d 14?5?6 会被马上执行Q而Q?17~20 则会抛出异常。最l顺序是Q????4?5?6???????0?1?2?3。下面是一个线E池使用的例子:

view plaincopy to clipboardprint?
public static void main(String[] args) {  
    BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();  
    ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 6, 1, TimeUnit.DAYS, queue);  
   
    for (int i = 0; i < 20; i++) {  
        executor.execute(new Runnable() {  
   
            public void run() {  
                try {  
                    Thread.sleep(1000);  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
                System.out.println(String.format("thread %d finished", this.hashCode()));  
            }  
        });  
    }  
    executor.shutdown();  
}
public static void main(String[] args) {
    BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
    ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 6, 1, TimeUnit.DAYS, queue);

    for (int i = 0; i < 20; i++) {
        executor.execute(new Runnable() {

            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(String.format("thread %d finished", this.hashCode()));
            }
        });
    }
    executor.shutdown();
}


对这个例子的说明如下Q?/p>


1、BlockingQueue 只是一个接口,常用的实现类?LinkedBlockingQueue ?ArrayBlockingQueue。用 LinkedBlockingQueue 的好处在于没有大限制。这L(fng)话,因ؓ队列不会满,所?execute() 不会抛出异常Q而线E池中运行的U程C永远不会过 corePoolSize 个,keepAliveTime 参数也就没有意义了?/p>

2、shutdown() Ҏ(gu)不会d。调?shutdown() Ҏ(gu)之后Q主U程马上结束了Q而线E池会l运行直到所有Q务执行完才会停止。如果不调用 shutdown() Ҏ(gu)Q那么线E池会一直保持下去,以便随时d新的d?/p>

到这里对于这个线E池q只是介l了一部分。ThreadPoolExecutor h很强的可扩展性,不过扩展它的前提是要熟?zhn)它的工作方式。后面的文章会介绍如何扩展 ThreadPoolExecutor cR?/p>

 

本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/YidingHe/archive/2009/02/14/3889785.aspx



大鸟 2009-08-17 09:49 发表评论
]]>
java中XML的四U解析器(dom,sax,jdom,dom4j)原理及性能比较http://www.tkk7.com/dunkbird/articles/291420.html大鸟大鸟Mon, 17 Aug 2009 01:46:00 GMThttp://www.tkk7.com/dunkbird/articles/291420.htmlhttp://www.tkk7.com/dunkbird/comments/291420.htmlhttp://www.tkk7.com/dunkbird/articles/291420.html#Feedback0http://www.tkk7.com/dunkbird/comments/commentRss/291420.htmlhttp://www.tkk7.com/dunkbird/services/trackbacks/291420.html

1QDOM(JAXP Crimson解析?
        DOM是用与^台和语言无关的方式表CXML文档的官方W3C标准。DOM是以层次l构l织的节Ҏ(gu)信息片断的集合。这个层ơ结构允许开发h员在?wi)中L 特定信息。分析该l构通常需要加载整个文档和构造层ơ结构,然后才能做Q何工作。由于它是基于信息层ơ的Q因而DOM被认为是Z?wi)或Z对象的。DOM 以及q义的基于树(wi)的处理具有几个优炏V首先,׃?wi)在内存中是持久的,因此可以修改它以便应用程序能?gu)据和l构作出更改。它q可以在M时候在?wi)中上?DQ而不是像SAX那样是一ơ性的处理。DOM使用h也要单得多?/font>

2QSAX

        SAX处理的优炚w常类g媒体的优点。分析能够立卛_始,而不是等待所有的数据被处理。而且Q由于应用程序只是在d数据时检查数据,因此不需要将?据存储在内存中。这对于大型文档来说是个巨大的优炏V事实上Q应用程序甚至不必解析整个文档;它可以在某个条g得到满时停止解析。一般来_SAXq比 它的替代者DOM快许多?
选择DOMq是选择SAXQ?对于需要自q写代码来处理XML文档的开发h员来_ 选择DOMq是SAX解析模型是一个非帔R要的设计决策?DOM采用建立?wi)Şl构的方式访问XML文档Q而SAX采用的事件模型?

  DOM解析器把XML文档转化Z个包含其内容??wi),q可以对?wi)进行遍历。用DOM解析模型的优Ҏ(gu)~程Ҏ(gu)Q开发h员只需要调用徏?wi)的指oQ然后利用navigation APIs讉K所需的树(wi)节点来完成Q务。可以很Ҏ(gu)的添加和修改?wi)中的元素。然而由于用DOM解析器的时候需要处理整个XML文档Q所以对性能和内存的?求比较高Q尤其是遇到很大的XML文g的时候。由于它的遍历能力,DOM解析器常用于XML文档需要频J的改变的服务中?

  SAX解析器采用了Z事g的模型,它在解析 XML文档的时候可以触发一pd的事Ӟ当发现给定的tag的时候,它可以激zM个回调方法,告诉该方法制定的标签已经扑ֈ。SAX对内存的要求通常会比 较低Q因为它让开发h员自己来军_所要处理的tag。特别是当开发h员只需要处理文档中所包含的部分数据时QSAXq种扩展能力得到了更好的体现。但?SAX解析器的时候编码工作会比较困难Q而且很难同时讉K同一个文档中的多处不同数据?

3QJDOM           http://www.jdom.org/

          JDOM的目的是成ؓJava特定文档模型Q它化与XML的交互ƈ且比使用DOM实现更快。由于是W一个Java特定模型QJDOM一直得到大力推q和 促进。正在考虑通过“Java规范hJSR-102”它最l用?#8220;Java标准扩展”。从2000q初已l开始了JDOM开发?

  JDOM与DOM主要有两斚w不同。首先,JDOM仅用具体类而不使用接口。这在某些方面简化了APIQ但是也限制了灵zL。第二,API大量使用了Collectionsc,化了那些已经熟?zhn)q些cȝJava开发者的使用?

  JDOM文档声明其目的是“使用20%(或更? 的精力解?0%(或更?Java/XML问题”(Ҏ(gu)学习(fn)曲线假定?0%)。JDOM对于大多数Java/XML应用E序来说当然是有用的Qƈ且大 多数开发者发现API比DOMҎ(gu)理解得多。JDOMq包括对E序行ؓ的相当广泛检查以防止用户做Q何在XML中无意义的事。然而,它仍需要?zhn)充分理?XML以便做一些超出基本的工作(或者甚至理解某些情况下的错?。这也许是比学习(fn)DOM或JDOM接口都更有意义的工作?

  JDOM自n不包含解析器。它通常使用SAX2?析器来解析和验证输入XML文档(管它还可以以前构造的DOM表示作ؓ输入)。它包含一些{换器以将JDOM表示输出成SAX2事g、DOM模型?XML文本文档。JDOM是在Apache许可证变体下发布的开放源码?/font>

4QDOM4J http://dom4j.sourceforge.net/
            
        虽然DOM4J代表了完全独立的开发结果,但最初,它是JDOM的一U智能分支。它合ƈ了许多超出基本XML文档表示的功能,包括集成的XPath支持?XML Schema支持以及用于大文档或化文档的基于事件的处理。它q提供了构徏文档表示的选项Q它通过DOM4J API和标准DOM接口hq行讉K功能。从2000下半q开始,它就一直处于开发之中?

  为支持所有这些功能,DOM4J使用接口和抽象基 本类Ҏ(gu)。DOM4J大量使用了API中的Collectionsc,但是在许多情况下Q它q提供一些替代方法以允许更好的性能或更直接的编码方法。直?好处是,虽然DOM4J付出了更复杂的API的代P但是它提供了比JDOM大得多的灉|性?

  在添加灵zL、XPath集成和对大文档处理的?标时QDOM4J的目标与JDOM是一L(fng)Q针对Java开发者的易用性和直观操作。它q致力于成ؓ比JDOM更完整的解决Ҏ(gu)Q实现在本质上处理所?Java/XML问题的目标。在完成该目标时Q它比JDOM更少防止不正的应用E序行ؓ?

  DOM4J是一个非帔R怼U的Java XML APIQ具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的Y件。如今你可以看到来多的Java软g都在使用DOM4J来读?XMLQ特别值得一提的是连Sun的JAXM也在用DOM4J?


2.. 比较

1QDOM4J性能最好,qSun的JAXM也在用DOM4J。目前许多开源项目中大量采用DOM4JQ例如大名鼎鼎的Hibernate也用DOM4J来读取XML配置文g。如果不考虑可移植性,那就采用DOM4J.

2QJDOM和DOM在性能试时表C佻I在测?10M文档时内存溢出。在文档情况下q值得考虑使用DOM和JDOM。虽然JDOM的开发者已l说明他们期望在正式发行版前专注性能问题Q但是从性能?Ҏ(gu)看,它确实没有值得推荐之处。另外,DOM仍是一个非常好的选择。DOM实现q泛应用于多U编E语a。它q是许多其它与XML相关的标准的基础Q因?它正式获得W3C推荐(与基于非标准的Java模型相对)Q所以在某些cd的项目中可能也需要它(如在JavaScript中用DOM)?/font>

3QSAX表现较好Q这要依赖于它特定的解析方式Q事仉动。一个SAX即到来的XML,但ƈ没有载入到内?当然当XML被dӞ会有部分文档暂时隐藏在内存中)?/font>

3. 四种xml操作方式的基本用方?/font>

xml文gQ?/font>

<?xml version="1.0" encoding="utf-8" ?>
<Result>
   <VALUE>
       <NO DATE="2005">A1</NO>
       <ADDR>GZ</ADDR>
   </VALUE>
   <VALUE>
       <NO DATE="2004">A2</NO>
       <ADDR>XG</ADDR>
</VALUE>
</Result>

1QDOM

import java.io.*;
import java.util.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;

public class MyXMLReader{
public static void main(String arge[]){

  long lasting =System.currentTimeMillis();
try{
File f=new File("data_10k.xml");
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Document doc = builder.parse(f);
NodeList nl = doc.getElementsByTagName("VALUE");
for (int i=0;iQnl.getLength();i++){
System.out.print("车牌L(fng):" + doc.getElementsByTagName("NO").item(i).getFirstChild().getNodeValue());
System.out.println("车主地址:" + doc.getElementsByTagName("ADDR").item(i).getFirstChild().getNodeValue());
}
}catch(Exception e){
e.printStackTrace();
}

2QSAX

import org.xml.sax.*;
import org.xml.sax.helpers.*;
import javax.xml.parsers.*;

public class MyXMLReader extends DefaultHandler {

 java.util.Stack tags = new java.util.Stack();
public MyXMLReader() {
super();
   }

 public static void main(String args[]) {
long lasting = System.currentTimeMillis();
try {
SAXParserFactory sf = SAXParserFactory.newInstance();
SAXParser sp = sf.newSAXParser();
MyXMLReader reader = new MyXMLReader();
sp.parse(new InputSource("data_10k.xml"), reader);
} catch (Exception e) {
e.printStackTrace();
}

  System.out.println("q行旉Q? + (System.currentTimeMillis() - lasting) + "毫秒");}
public void characters(char ch[], int start, int length) throws SAXException {
String tag = (String) tags.peek();
if (tag.equals("NO")) {
System.out.print("车牌L(fng)Q? + new String(ch, start, length));
    }
    if (tag.equals("ADDR")) {
System.out.println("地址:" + new String(ch, start, length));
    }
   }

  public void startElement(String uri,String localName,String qName,Attributes attrs) {
tags.push(qName);}
}

3Q?JDOM

import java.io.*;
import java.util.*;
import org.jdom.*;
import org.jdom.input.*;

public class MyXMLReader {

 public static void main(String arge[]) {
long lasting = System.currentTimeMillis();
try {
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(new File("data_10k.xml"));
Element foo = doc.getRootElement();
List allChildren = foo.getChildren();
for(int i=0;iQallChildren.size();i++) {
System.out.print("车牌L(fng):" + ((Element)allChildren.get(i)).getChild("NO").getText());
System.out.println("车主地址:" + ((Element)allChildren.get(i)).getChild("ADDR").getText());
}
} catch (Exception e) {
e.printStackTrace();
}

}

4QDOM4J

import java.io.*;
import java.util.*;
import org.dom4j.*;
import org.dom4j.io.*;

public class MyXMLReader {

 public static void main(String arge[]) {
long lasting = System.currentTimeMillis();
try {
File f = new File("data_10k.xml");
SAXReader reader = new SAXReader();
Document doc = reader.read(f);
Element root = doc.getRootElement();
Element foo;
for (Iterator i = root.elementIterator("VALUE"); i.hasNext();) {
foo = (Element) i.next();
System.out.print("车牌L(fng):" + foo.elementText("NO"));
System.out.println("车主地址:" + foo.elementText("ADDR"));
}
} catch (Exception e) {
e.printStackTrace();
    }


大鸟 2009-08-17 09:46 发表评论
]]>
java字节和字符?/title><link>http://www.tkk7.com/dunkbird/articles/279552.html</link><dc:creator>大鸟</dc:creator><author>大鸟</author><pubDate>Tue, 02 Jun 2009 05:14:00 GMT</pubDate><guid>http://www.tkk7.com/dunkbird/articles/279552.html</guid><wfw:comment>http://www.tkk7.com/dunkbird/comments/279552.html</wfw:comment><comments>http://www.tkk7.com/dunkbird/articles/279552.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/dunkbird/comments/commentRss/279552.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/dunkbird/services/trackbacks/279552.html</trackback:ping><description><![CDATA[<p style="margin: 0cm 0cm 0pt"><span style="font-size: small"><span style="font-family: Times New Roman">Java</span>操?/span></p> <p> <br /> <span style="font-size: medium; background-color: #ff0000">对于我们常用的GBK中,英文是占?个字节,中文??<br /> 对于UTF-8Q英文是1个,中文??<br /> 对于UnicodeQ英文中文都??/span></p> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small"><span style="font-family: Times New Roman">Java</span>的流操作分ؓ字节和字符两U?/span></p> <p style="margin: 0cm 0cm 0pt 18pt; text-indent: -18pt"><span style="font-family: Times New Roman"><span style="font-size: small">1?nbsp;</span></span><span style="font-size: small">字节?/span></p> <p style="margin: 0cm 0cm 0pt 18pt"><span style="font-size: small">所有的L作都l承自一个公pc?span style="font-family: Times New Roman">java.io.InputStream</span>cR?/span></p> <p style="margin: 0cm 0cm 0pt 18pt"><span style="font-size: small">所有的写操作都l承自一个公pc?span style="font-family: Times New Roman">java.io.OutputStream</span>cR?/span></p> <p style="margin: 0cm 0cm 0pt 18pt"><span style="font-size: small"><span style="font-family: Times New Roman">InputStream</span>?span style="font-family: Times New Roman">OutputStream</span>都是抽象cR?/span></p> <p style="margin: 0cm 0cm 0pt 18pt"><span style="font-size: small"><span style="font-family: Times New Roman">InputStream</span>?span style="font-family: Times New Roman">6</span>个低U输入流Q?/span></p> <table style="border-collapse: collapse" cellspacing="0" cellpadding="0" border="1"> <tbody> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">低񔋹?/span></p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 213.05pt; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">的用?/span></p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small; font-family: Times New Roman">ByteArrayInputStream</span></p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">从内存数l中d数据字节</span></p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small; font-family: Times New Roman">FileInputStream</span></p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">从本地文件系l中d数据字节</span></p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small; font-family: Times New Roman">PipedInputStream</span></p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">从线E管道中d数据字节</span></p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small; font-family: Times New Roman">StringBufferInputStream</span></p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">从字W串中读取数据字?/span></p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small; font-family: Times New Roman">SequenceInputStream</span></p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">从两个或多个低񔋹中d数据字节Q当到达的末尾时从一个流转到另一个流</span></p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small; font-family: Times New Roman">System.in</span></p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">从用h制台d数据字节</span></p> </td> </tr> </tbody> </table> <p style="margin: 0cm 0cm 0pt 18pt"><span style="font-size: small"><span style="font-family: Times New Roman">InputStream</span>q有一个子c:qo器流<span style="font-family: Times New Roman">java.io.FilterInputStream</span>。过滤器即能把基本包裹v来,提供更多方便的用法?/span></p> <p style="margin: 0cm 0cm 0pt 18pt"><span style="font-size: small"><span style="font-family: Times New Roman">FilterInputStream </span>cȝ构造方法ؓ<span style="font-family: Times New Roman">FilterInputStream(InputStream)</span>Q在指定的输入流之上Q创Z个输入流qo器?/span></p> <p style="margin: 0cm 0cm 0pt 18pt"><span style="font-size: small"><span style="font-family: Times New Roman">FilterInputStream</span>的常用的子类如下Q?/span></p> <table style="border-collapse: collapse" cellspacing="0" cellpadding="0" border="1"> <tbody> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">qo器输入流</span></p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 213.05pt; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">的用?/span></p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small; font-family: Times New Roman">BufferedInputStream</span></p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">~冲区对数据的访问,以提高效?/span></p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small; font-family: Times New Roman">DataInputStream</span></p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">从输入流中读取基本数据类型,?span style="font-family: Times New Roman">int</span>?span style="font-family: Times New Roman">float</span>?span style="font-family: Times New Roman">double</span>或者甚至一行文?/span></p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small; font-family: Times New Roman">LineNumberInputStream</span></p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">在翻译行l束W的基础上,l护一个计数器Q该计数器表明正在读取的是哪一行?/span></p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small; font-family: Times New Roman">PushbackInputStream</span></p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">允许把数据字节向后推到流的首?/span></p> </td> </tr> </tbody> </table> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small"><span style="font-family: Times New Roman">OutputStream</span>Q略Q?/span></p> <p style="margin: 0cm 0cm 0pt; text-indent: 18pt"><span style="font-size: small"><span style="font-family: Times New Roman">OutputStream</span>的结构基本和<span style="font-family: Times New Roman">InputStream</span>是一L(fng)?/span></p> <p style="margin: 0cm 0cm 0pt 18pt; text-indent: -18pt"><span style="font-family: Times New Roman"><span style="font-size: small">2?nbsp;</span></span><span style="font-size: small">字符?/span></p> <p style="margin: 0cm 0cm 0pt 18pt"><span style="font-size: small">注:是在<span style="font-family: Times New Roman">jdk1.1</span>里面引进的,上面字节是?span style="font-family: Times New Roman">jdk1.0</span>引进的。当用于处理文本数据Ӟ选择字符比字节更好。但对只\基本数据cd的开发者,可以l箋使用字节?/span></p> <p style="margin: 0cm 0cm 0pt 18pt"><span style="font-size: small">所有的L作都l承自一个公pc?span style="font-family: Times New Roman">java.io.Reader</span>cR?/span></p> <p style="margin: 0cm 0cm 0pt 18pt"><span style="font-size: small">所有的写操作都l承自一个公pc?span style="font-family: Times New Roman">java.io.Writer</span>cR?/span></p> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small"><span style="font-family: Times New Roman">       </span>同样<span style="font-family: Times New Roman">Reader</span>?span style="font-family: Times New Roman">Writer</span>也是抽象cR?/span></p> <p style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-size: small"><span style="font-family: Times New Roman">Reader</span>的常用的子类如下Q?/span></p> <table style="border-collapse: collapse" cellspacing="0" cellpadding="0" border="1"> <tbody> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">低d?/span></p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 213.05pt; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">的用?/span></p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt">CharArrayReader</p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">从字W数l中d数据</span></p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt">InputStreamReader</p> <p> </p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p> </p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-size: small"><span style="font-family: Times New Roman">FileReader</span>QInputStreamReader的子c) </span></p> <p> </p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">从本地文件系l中d字符序列</span></p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt">StringReader</p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">从字W串中读取字W序?/span></p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt">PipedReader</p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 213.05pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="284"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">从线E管道中d字符序列</span></p> </td> </tr> </tbody> </table> <p style="margin: 0cm 0cm 0pt; text-indent: 21pt">InputStreamReader重点讲解Q?/p> <p style="margin: 0cm 0cm 0pt; text-indent: 21pt">InputStreamReader是从输入中d数据Q连接输入流于读取器。如Q?/p> <p style="margin: 0cm 0cm 0pt 21pt; text-indent: 21pt"><span style="font-size: 12pt"><span style="font-family: Times New Roman">new InputStreamReader(System.in) </span></span></p> <p style="margin: 0cm 0cm 0pt"><span style="font-size: 12pt"><span style="font-family: Times New Roman">       </span></span>构造方法:</p> <p style="margin: 0cm 0cm 0pt; text-indent: 21pt; text-align: left" align="left">InputStreamReader<span style="color: #000000">(InputStream) </span></p> <p style="margin: 0cm 0cm 0pt 21pt; text-indent: 21pt; text-align: left" align="left">用缺省的字符~码方式Q创Z?InputStreamReader?/p> <p style="margin: 0cm 0cm 0pt; text-indent: 21pt; text-align: left" align="left"><a href="http://mce_host/admin/blogs/185580/mk:@MSITStoreF:/_֍/jdk.chm::"><span style="color: windowtext; text-decoration: none">InputStreamReader</a><span style="color: #000000">(InputStream, String) </span></span></p> <p style="margin: 0cm 0cm 0pt 21pt; text-indent: 21pt; text-align: left" align="left">用已命名的字W编码方式,创徏一?InputStreamReader?/p> <p style="margin: 0cm 0cm 0pt"><span style="font-size: 12pt"><span style="font-family: Times New Roman">       </span></span>常用的过滤器d器:</p> <table style="border-collapse: collapse" cellspacing="0" cellpadding="0" border="1"> <tbody> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 221.4pt; padding-top: 0cm; background-color: transparent" valign="top" width="295"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">qo器读取器 </span></p> <p> </p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 204.7pt; padding-top: 0cm; background-color: transparent" valign="top" width="273"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">的用?/span></p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 221.4pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="295"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small; font-family: Times New Roman">BufferedReader</span></p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 204.7pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="273"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">~冲数据的访问,以提高效?/span></p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 221.4pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="295"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small"><span style="font-family: Times New Roman"> LineNumberReader</span>Q?span style="font-family: Times New Roman">BufferedReader</span>的子c)</span></p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 204.7pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="273"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">l护一个计数器Q该计数器表明正在读取的是哪一行?/span></p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 221.4pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="295"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small"><span style="font-family: Times New Roman">FilterReader</span>Q抽象类Q?/span></p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 204.7pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="273"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">提供一个类创徏qo器时可以扩展q个c?/span></p> </td> </tr> <tr> <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 221.4pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="295"> <p style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-size: small"><span style="font-family: Times New Roman">PushbackReader</span>Q?span style="font-family: Times New Roman">FilterReader</span>的子c)</span></p> </td> <td style="padding-right: 5.4pt; padding-left: 5.4pt; border-left-color: #d4d0c8; padding-bottom: 0cm; width: 204.7pt; border-top-color: #d4d0c8; padding-top: 0cm; background-color: transparent" valign="top" width="273"> <p style="margin: 0cm 0cm 0pt"><span style="font-size: small">允许把文本数据推回到d器的中</span></p> </td> </tr> </tbody> </table> <p style="margin: 0cm 0cm 0pt; text-indent: 21pt">q些qo器读取器都可以传入一?span style="font-size: 12pt"><span style="font-family: Times New Roman">Reader</span></span>作ؓ构造方法的参数?/p> <p style="margin: 0cm 0cm 0pt; text-indent: 21pt"><span style="font-size: 12pt"><span style="font-family: Times New Roman">Writer</span></span>Q略Q?/p> <p style="margin: 0cm 0cm 0pt 21pt; text-indent: 21pt"><span style="font-size: small"><span style="font-family: Times New Roman">Writer</span>的结构基本和<span style="font-family: Times New Roman">Reader</span>是一L(fng)?/span></p> <p style="margin: 0cm 0cm 0pt 21pt; text-indent: 21pt"><span style="font-size: small">字节是最基本的,字符是Z处理字符而提出来的?/span></p> <p style="margin: 0cm 0cm 0pt 21pt; text-indent: 21pt"><span style="font-size: small">new BufferedReader(new InputStreamReader(client.getInputStream()));解释Q?/span></p> <p style="margin: 0cm 0cm 0pt 21pt; text-indent: 21pt"><span style="font-size: small">client.getInputStream()是字节流Q?/span></p> <p style="margin: 0cm 0cm 0pt 21pt; text-indent: 21pt"><span style="font-size: small">InputStreamReader把字节流转换成字W流Q?/span></p> <p style="margin: 0cm 0cm 0pt 21pt; text-indent: 21pt"><span style="font-size: small">BufferedReader~冲字符,使得能够使用readline(){方法,直接d一行?/span></p> <p> <p> <p> <p> </p> <img src ="http://www.tkk7.com/dunkbird/aggbug/279552.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/dunkbird/" target="_blank">大鸟</a> 2009-06-02 13:14 <a href="http://www.tkk7.com/dunkbird/articles/279552.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于J2EE Tranaction的几个基本概?/title><link>http://www.tkk7.com/dunkbird/articles/242856.html</link><dc:creator>大鸟</dc:creator><author>大鸟</author><pubDate>Wed, 26 Nov 2008 11:09:00 GMT</pubDate><guid>http://www.tkk7.com/dunkbird/articles/242856.html</guid><wfw:comment>http://www.tkk7.com/dunkbird/comments/242856.html</wfw:comment><comments>http://www.tkk7.com/dunkbird/articles/242856.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/dunkbird/comments/commentRss/242856.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/dunkbird/services/trackbacks/242856.html</trackback:ping><description><![CDATA[<p style="text-indent: 2em">Transaction不管在J2EEq是.NET领域中都是相当重要的一个组成部分。尽很多与Transaction相关的概念在两个不同的^C都是盔R的Q但是它们在Transaction的实现方面却有着很多的不同。想?NET下的Transaction有更深入了解的朋友,可以参?a >idior</a>兄写?a >Transaction in ADO.net 2.0</a>。在以下的篇q里面,我就J2EE中与Transaction相关的几个概念做些讲q?/p> <p style="text-indent: 2em">        1.什么是TransactionQ所谓Transaction是指一pd不可分割的改动数据库的操作。在q个解释中,有三个关键词Q一pdQ不可分割以及改动。仅仅是一个改动数据库的操作是没有Transaction可言Q只?#8220;一pd”操作(一lSQL语句)才可能组成TransactionQ?#8220;不可分割”意味着一致性和完整性,要么q一pd操作全部commitQ要么就全部rollbackQ如果一pd的操作只包含enquiry操作Q那么这些操作也不是Transaction?nbsp;</p> <p style="text-indent: 2em">        2.在J2EE中,Transaction主要有几大类Q具体有几种Q在J2EE中,Transaction主要有Bean-Managed Transaction和Container-Managed Transaction两大cR其中在Bean-Managed Transaction中还会分为JDBC Transaction和JTA Transaction两种?/p> <p style="text-indent: 2em">        3.什么是JDBC TransactionQ它有怎样的特点?JDBC Transaction是指由Database本nȝ理的事务。其最大的特点是通过昄调用Connection接口的commit和rollbackҎ(gu)来完成事务的提交和回滚。事务结束的边界是commit或者rollbackҎ(gu)的调用,而开始的边界则不是那么明显了Q它会开始于l成当前事务的所有statement中的W一个被执行的时候。具体代码如下:</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" border="0" alt="" /><img src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" border="0" alt="" />class CreditDAoImpl implements CreditDAO <img src="http://www.cnblogs.com/Images/dot.gif" border="0" alt="" />{</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />    Connection conn = getConnection();</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" border="0" alt="" /><img src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" border="0" alt="" />    public void transfer(Currency amount, Account fromAccount, Account toAccount) throws CreditException <img src="http://www.cnblogs.com/Images/dot.gif" border="0" alt="" />{</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" border="0" alt="" /><img src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" border="0" alt="" />        try <img src="http://www.cnblogs.com/Images/dot.gif" border="0" alt="" />{</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />             conn.setAutoCommit(false);</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />             depositToAccount(conn, toAccount, amount);</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />             withdrawFromAccount(conn, fromAccount, amount);     </p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />             conn.commit();</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" border="0" alt="" /><img src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" border="0" alt="" />        } catch (Exception e) <img src="http://www.cnblogs.com/Images/dot.gif" border="0" alt="" />{</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" border="0" alt="" /><img src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" border="0" alt="" />            try <img src="http://www.cnblogs.com/Images/dot.gif" border="0" alt="" />{</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />                 conn.rollback();</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />                 throw new CreditException(e.getMessage());</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" border="0" alt="" /><img src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" border="0" alt="" />            } catch (SQLException e1) <img src="http://www.cnblogs.com/Images/dot.gif" border="0" alt="" />{</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />                 throw new CreditException(e.getMessage());</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" border="0" alt="" />            }                       </p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" border="0" alt="" />        } </p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" border="0" alt="" />    }</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" border="0" alt="" />}</p> <p style="text-indent: 2em">        4.什么是JTA TransactionQ它有怎样的特点呢QJTA Transaction是指由J2EE Transaction managerȝ理的事务。其最大的特点是调用UserTransaction接口的beginQcommit和rollbackҎ(gu)来完成事务范围的界定Q事务的提交和回滚。JTA Transaction可以实现同一事务对应不同的数据库Q但是它仍然无法实现事务的嵌套。具体的代码如下[1]Q?/p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" border="0" alt="" /><img src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" border="0" alt="" />public void withdrawCash(double amount) <img src="http://www.cnblogs.com/Images/dot.gif" border="0" alt="" />{</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />   UserTransaction ut = context.getUserTransaction();</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" border="0" alt="" /><img src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" border="0" alt="" />   try <img src="http://www.cnblogs.com/Images/dot.gif" border="0" alt="" />{</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />      ut.begin();</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />      updateChecking(amount);</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />      machineBalance -= amount;</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />      insertMachine(machineBalance);</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />      ut.commit();</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" border="0" alt="" /><img src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" border="0" alt="" />   } catch (Exception ex) <img src="http://www.cnblogs.com/Images/dot.gif" border="0" alt="" />{</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" border="0" alt="" /><img src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" border="0" alt="" />       try <img src="http://www.cnblogs.com/Images/dot.gif" border="0" alt="" />{</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />          ut.rollback();</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" border="0" alt="" /><img src="http://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif" border="0" alt="" />       } catch (SystemException syex) <img src="http://www.cnblogs.com/Images/dot.gif" border="0" alt="" />{</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />           throw new EJBException</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />              ("Rollback failed: " + syex.getMessage());</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" border="0" alt="" />       }</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />       throw new EJBException </p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif" border="0" alt="" />          ("Transaction failed: " + ex.getMessage());</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" border="0" alt="" />    }</p> <p style="text-indent: 2em"><img src="http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" border="0" alt="" />}</p> <p style="text-indent: 2em">        5.什么是Container-Managed TransactionQ它又有怎样的特点呢QContainer-Managed TransactionQ顾名思义Q就是由Container负责理的TransactionQ当然这样Transaction是出现在EJB的范畴中。Container-Managed Transaction最大的特点是不需要显式界定事务的边界Q也不需要显式的提交或者回滚事务,q一切都由Container来替我们完成。我们需要做的就是设定在一个Bean中,哪些Ҏ(gu)是跟事务相关的,同时讑֮它们的Transaction Attribute既可?/p> <p style="text-indent: 2em">        Transaction的Scope是相当重要的Q特别是在一个Bean的方法中调用另外一个Bean的方法。ؓ了便于说明问题,我们把这两个Ҏ(gu)分别UCؓmethodA和methodB。当methodA调用methodB的时候,methodB在事务的层面上对调用者methodA有怎样的限?methodB中是否存在事?以及methodA如何在事务的层面上实现对methodB的调?是否需要重新创Z个新的事务来处理methodB的调?都需要通过Transaction Attribute来设定的。具体的Transaction Attribute有以下六U:RequiredQRequiresNewQMandatoryQNotSupportedQSupports和Never。有关Transaction Attribute的介l,可以参阅J2EE Tutorial?a >关于Container-Managed Transaction的介l?/a>?/p> <p style="text-indent: 2em">        [1] 代码来自SUN的J2EE Tutorial中关?a >Bean-Managed Transaction</a>的介l?</p> <img src ="http://www.tkk7.com/dunkbird/aggbug/242856.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/dunkbird/" target="_blank">大鸟</a> 2008-11-26 19:09 <a href="http://www.tkk7.com/dunkbird/articles/242856.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Bean托管事务在J2EE中的挂vhttp://www.tkk7.com/dunkbird/articles/242853.html大鸟大鸟Wed, 26 Nov 2008 11:00:00 GMThttp://www.tkk7.com/dunkbird/articles/242853.htmlhttp://www.tkk7.com/dunkbird/comments/242853.htmlhttp://www.tkk7.com/dunkbird/articles/242853.html#Feedback0http://www.tkk7.com/dunkbird/comments/commentRss/242853.htmlhttp://www.tkk7.com/dunkbird/services/trackbacks/242853.html【IT168技术文档?br />
  (zhn)有没有惌Qؓ什么会有六U事务划分属性(NotSupported、Required、Supports、RequiresNew、Mandatory和NeverQ?q六U都是由容器托管事务 (CMT)的bean来支持的Q但如果使用的是bean托管事务(BMT)QEJB规范所能提供的功能N只有通过UserTransaction接口启动和提?回滚事务吗?昄QCMT模型好像更强大,比如QBMT不能使当前事务挂L(fng)后恢复,q就意味着在BMT bean中无法仿真RequiresNew和NotSupported划分Q至是在用UserTransaction接口时?

  虽然EJB规范q没有解释ؓ什么会存在以上所提到的不对称情况Q但是在BMT模型中依然有一U用来事务挂v然后恢复的合法方式。如果曾l研I过javax.transaction包的内容Q?zhn)可能会注意到Q与UserTransaction接口一L(fng)q有一个TransactionManager接口Q它看v来就像一个扩展的UserTransactionQ同L(fng)Ҏ(gu)——begin()、commit()和rollback()Q再加上suspend()和resume()?

  如果能从EJB中得C个TransactionManager实现Q我们就可以实现~程式地使事务挂L(fng)后恢复的目标。虽然J2EE 1.3和EJB 2.0规范都未提到TransactionManager的可用性,但它们也都没有明表C禁止用它。此外,对于CMT事务划分Q容器是从内部用Java Transaction API (JTA)Q因此,我们几乎可以100%地肯定:TransactionManager是存在的Q惟一的问题只是在代码中获得对它的引用?

  在这文章中Q我们将了解如何利用几个行的容器来获得一个TransactionManagerQ以及如何用它来扩展bean托管事务的功能,使它们和容器托管事务一样强大。我们也简qC些涉及用这些高U功能的风险Q在文章的结,我们q将探讨如何在流行的Spring框架中用TransactionManager?

  在各UJ2EE服务器中获得TransactionManager的引?

  J2EE和EJB规范没有描述M获得TransactionManager引用的标准方法,每个J2EE容器供应商可以随意将其放|在M地方Q甚至不需提供M机制Q就可以从应用程序代码中对它q行讉K。但在实践中Q如今所有的容器都有获取它的机制。以下是一些如何从最行的J2EE容器获得TransactionManager引用的例子?

  抛出一个UserTransaction (WebLogic、Orion、OC4J)

  M一个兼容J2EE的容器都必须使UserTransaction对象在JNDI中的java:comp/UserTransaction下可用。因为UserTransaction接口是TransactionManager的子集,所以一些J2EE容器供应商选择为它们提供一U通用的实现。WebLogic 8、Orion 2和Oracle的OC4J EJB3预览版都是这U方法的例子。在q些容器中,只要从JNDI中获得一个UserTransaction对象Q再把它转到TransactionManagerQ就可以获得对TransactionManager的引用。这可能是最单的一U情c?
private TransactionManager getFromUserTransaction()
throws Exception{
InitialContext ctx = new InitialContext();
UserTransaction ut = (UserTransaction)
ctx.lookup("java:comp/UserTransaction");
if (ut instanceof TransactionManager){
log("UserTransaction also TransactionManager");
return (TransactionManager)ut;
}
return null;
}
直接从JNDI中获取TransactionManager (JBoss、WebLogic)

  在JBoss 3和W(xu)ebLogic 8中,可从JNDI获取TransactionManagerQ虽然名UC一PQ因此可以通过单的查找而获得:

private TransactionManager getFromJNDI()
throws Exception {
InitialContext ctx = new InitialContext();
try {
// WebLogic
return (TransactionManager)
ctx.lookup("javax.transaction.TransactionManager");
}
catch (Exception e) { }

try {
// JBoss
return (TransactionManager)
ctx.lookup("java:/TransactionManager");
}
catch (Exception e) { }
return null;
}



从一个定制的工厂获取TransactionManager (Websphere)

  在WebSphere 4/5/6中,TransactionManager的引用要从工厂类中获取。但是,ȝ的是Q工厂类的名U随WebSphere版本的不同而有所改变?

public TransactionManager getFromWebsphereFactory()
throws Exception{
try{
// WebSphere 5.1 or 6.0
return
com.ibm.ws.Transaction.TransactionManagerFactory
.getTransactionManager();
}
catch (ClassNotFoundException ex){}

try{
// WebSphere 5.0
return
com.ibm.ejs.jts.jta.TransactionManagerFactory
.getTransactionManager();
}
catch (ClassNotFoundException ex){}

try{
// WebSphere 4.0
com.ibm.ejs.jts.jta.JTSXA..getTransactionManager();
}
catch (ClassNotFoundException ex){ }

return null;
}



大鸟 2008-11-26 19:00 发表评论
]]>
【JBoss学习(fn)】EclipseQJBoss学习(fn)入门http://www.tkk7.com/dunkbird/articles/204110.html大鸟大鸟Fri, 30 May 2008 07:52:00 GMThttp://www.tkk7.com/dunkbird/articles/204110.htmlhttp://www.tkk7.com/dunkbird/comments/204110.htmlhttp://www.tkk7.com/dunkbird/articles/204110.html#Feedback0http://www.tkk7.com/dunkbird/comments/commentRss/204110.htmlhttp://www.tkk7.com/dunkbird/services/trackbacks/204110.html 

刚刚开始学?fn)JBossQ学?fn)了一个入门的小例子Q对于刚接触JBoss和Eclipse的菜鸟来说很有帮助的Q现在把我的试验q程介绍一下?br /> 首先Q打开EclipseQ新建——其它——JBoss IDE——J2EE Projects——J2EE 1.4 Projects
下一?br /> 填入目名称QHelloWorld
目内容可以选择使用~省值或者自己制定存储空?br /> 下一?br /> 在源选单下,d文g夹,分别命名为j2srcQ存放java文gQ和srcQ存N|文ӞQ缺省输出文件夹改ؓQHelloWorld/bin
完成

在包资源理器中Q右键单击j2srcQ选择新徏——包Q输入包名:sample.server?/font>

右键单击sample.serverQ选择新徏——接口,输入接口名字QHelloWorldQ此E接口,是指对于客户端而言所能看到的调用接口Q该接口内容为:

/**
 *HelloWorld.java
 */
package sample.server;

import javax.ejb.EJBObject;

/**
 * @author Administrator
 *
 * TODO 要更Ҏ(gu)生成的类型注释的模板Q请转至
 * H口 Q?首选项 Q?Java Q?代码样式 Q?代码模板
 */
public interface HelloWorld extends EJBObject {
 public String hello() throws java.rmi.RemoteException;
}

同样的,新徏Home接口HelloWorldHomeQ我们可以把Home接口看做是一个制造EJB的工厂,它告诉EJB容器Q?#8220;我的客户要我生成一个EJBQ现在我把这个Q务交l你啦!”
/**
 * HelloWorldHome.java
 */
package sample.server;
import javax.ejb.EJBHome;
/**
 * @author Administrator
 *
 * TODO 要更Ҏ(gu)生成的类型注释的模板Q请转至
 * H口 Q?首选项 Q?Java Q?代码样式 Q?代码模板
 */
public interface HelloWorldHome extends EJBHome {
 HelloWorld create() throws java.rmi.RemoteException,
   javax.ejb.CreateException;
}
下面是EJB的实玎ͼ右键单击sample.serverQ新建——其它——JBoss IDE——EJB Components——Session BeanQ输入名UͼHelloWorldBeanQ类型ؓStatelessQRemoteQ选择创徏来自类的构造函敎ͼl承的抽象方法,ejbCreate() method。完成?/font>

/**
 * HelloWorldBean.java
 */

package sample.server;

import java.rmi.RemoteException;

import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;

import javax.ejb.CreateException;

/**
 * @ejb.bean name="HelloWorld"
 *           display-name="Name for HelloWorld"
 *           description="Description for HelloWorld"
 *           jndi-name="ejb/HelloWorld"
 *           type="Stateless"
 *           view-type="remote"
 */
public class HelloWorldBean implements SessionBean {

 /**
  *
  */
 public HelloWorldBean() {
  super();
  // TODO 自动生成构造函数存?br />  }

 /* Q非 JavadocQ?br />   * @see javax.ejb.SessionBean#setSessionContext(javax.ejb.SessionContext)
  */
 public void setSessionContext(SessionContext ctx)
  throws EJBException,
  RemoteException {
  // TODO 自动生成Ҏ(gu)存根

 }

 /* Q非 JavadocQ?br />   * @see javax.ejb.SessionBean#ejbRemove()
  */
 public void ejbRemove() throws EJBException, RemoteException {
  // TODO 自动生成Ҏ(gu)存根

 }

 /* Q非 JavadocQ?br />   * @see javax.ejb.SessionBean#ejbActivate()
  */
 public void ejbActivate() throws EJBException, RemoteException {
  // TODO 自动生成Ҏ(gu)存根

 }

 /* Q非 JavadocQ?br />   * @see javax.ejb.SessionBean#ejbPassivate()
  */
 public void ejbPassivate() throws EJBException, RemoteException {
  // TODO 自动生成Ҏ(gu)存根

 }

 /**
  * Default create method
  *
  * @throws CreateException
  * @ejb.create-method
  */
 public void ejbCreate() throws CreateException {
  // TODO Auto-generated method stub
 }
 public String hello()
 {
  System.out.println("hello()");
  return "Hello,world";
 }
}
服务器端E序~好Q下一步就要做部v工作了?/font>

右键选择srcQ新建目录META-INFQ在该目录下Q新建——其它——JBoss-IDE——Descriptors——EJB 2.1 Deployment DescriptorQ默认名字ؓejb-jar.xmlQ完成?br /> ejb-jar.xmlQ?/font>

?xml version="1.0" encoding="UTF-8"??br /> 《ejb-jar version="2.1"
 xmlns="  xmlns:xsi="  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
  《ejb-jar?br /> 《enterprise-beans?br />   《session?br />    《ejb-name》HelloWorldBean?ejb-name?br />    《home》sample.server.HelloWorldHome?home?br />    《remote》sample.server.HelloWorld?remote?br />    《ejb-class》sample.server.HelloWorldBean?ejb-class?br />    《session-type》Stateful?session-type?br />    《transaction-type》Bean?transaction-type?br />   ?session?br />  ?enterprise-beans?br /> ?ejb-jar?/font>

Q备注:在此Q由于网|C的原因Q将<>W号Ҏ(gu)了《》,所以,在实际应用中应改?lt;>Q以正常工作。同Ӟejb-jar.xml开头的版本标记文字会因jboss版本不同而不同,希望大家注意Q?!--l version="1.0" encoding="UTF-8-->

q样我们完成了一个简单的会话EJB的编写,下一步是打包?br /> 同时选择j2src和src两个目录Q右键单击选择导出——jar——选择导出目标Q可以放在定义的HelloWorld目录下,起个名字叫HelloWorld.jarQ则会在包资源管理器中看C个文件HelloWorld.jar?/font>

光有EJBQ没有客L(fng)Q对我们来说毫无用处Q所以下一步我们就要编写客L(fng)E序?br /> 同样的,在j2src下创建包sample.client?br /> 在该包下新徏c,cd为HelloWorldClientQ添加接口:sample.server.HelloWorldQ?br /> /**
 * HelloWorldClient.java
 */

sample.server.HelloWorldHome?/font>

package sample.client;

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.InitialContext;

import sample.server.HelloWorld;
import sample.server.HelloWorldHome;

/**
 * @author Administrator
 *
 * TODO 要更Ҏ(gu)生成的类型注释的模板Q请转至
 * H口 Q?首选项 Q?Java Q?代码样式 Q?代码模板
 */
public class HelloWorldClient{
 public static void main(String [] args){
  Hashtable env = new Hashtable();
  env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
  env.put(Context.PROVIDER_URL,"localhost:1099");
/**
 * 默认是把服务器端EJB部v在本ZQ如果部|在其它机器上,比如192.168.0.1Q则localhost  * 改ؓ192.168.0.1卛_
 */
  env.put("Java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
  try{
   Context ctx = new InitialContext(env);
   Object obj = ctx.lookup("HelloWorldBean");
   HelloWorldHome home =(HelloWorldHome)javax.rmi.PortableRemoteObject.narrow(
     obj, HelloWorldHome.class );
   HelloWorld helloWorld = home.create();
   System.out.println(helloWorld.hello());
   helloWorld.remove();
  }catch(Exception e){
   e.printStackTrace();
   System.out.println("Exception:"+e.getMessage());
  }   
 }
}

下面可以编译运行了?br /> 手动启动JBossQ直接运行JBoss\bin\目录下的run.bat卛_Q这个过E时间长短跟计算机的配置有关Q配|高的计机几秒钟就可以了,比较传统的计机则需要等?分多钟甚x长,不过你不需要专门等着它的q行Q你双击run.bat后,不用它Q你可以先做一些其他的事情Q比如给mm发条短信啊什么的Q等你发完短信后Q你会发现JBoss已经q行成功Qƈ会告诉你启动JBoss׃多长旉QStarted in 1m:36s:870msQ呵呵,我的机器比较传统哈?br /> 选择包资源管理器中的HelloWorld.jarQ右键单击选择Deployment——Deploy toQ?br /> 选择jboss 4.0(default)[file:/D:/jboss4/server/default/deploy/]
则系l会自动把HelloWorld.jar文g拯到jboss?server/default/deploy/目录下,jboss的运行窗口将出现
10:09:50,679 INFO  [EjbModule] Deploying HelloWorldBean
10:09:52,051 INFO  [org.jboss.ejb.EJBDeployer] Deployed: file:/D:/jboss4/server/default/deploy/HelloWorld.jar
服务器端q行成功
右键选择HelloWorldClient.javaQ选择q行——运行,在左辚w择java应用E序下的HelloWorldClientQ右辚w择c\径,在引导程序条目下d外部JARQ分别jboss的client目录下的jboss-j2ee.jar、log4j.jar、jboss-client.jar。然后单击运行,׃看到底下控制C昄?#8220;HelloQW(xu)orld”Q哈哈,成功了,q可跟一般的“HelloWorld”不太一样哦?/font>



大鸟 2008-05-30 15:52 发表评论
]]>
使用JBoss Eclipse IDE 开发J2EE应用pȝ(摘自jdon)http://www.tkk7.com/dunkbird/articles/204036.html大鸟大鸟Fri, 30 May 2008 02:50:00 GMThttp://www.tkk7.com/dunkbird/articles/204036.htmlhttp://www.tkk7.com/dunkbird/comments/204036.htmlhttp://www.tkk7.com/dunkbird/articles/204036.html#Feedback0http://www.tkk7.com/dunkbird/comments/commentRss/204036.htmlhttp://www.tkk7.com/dunkbird/services/trackbacks/204036.htmlJBoss推出的Eclipse IDE开发工兯来越强大Q当初刚刚推出来Ӟ因ؓ其内|xdoclet功能被h看好Q和Lomboz整合在一起开发J2EEQ可是,Lomoz不是那么好安装的Q至我自己安装5ơ成?ơ。同ӞJBoss的Eclipse IDE功能走向齐全Q比较成熟完备,只需要JBoss的Eclipse IDE可以,不必需要Lomboz了,我们开发一个J2EE应用E序完全没有必要那么ȝ了?

  JBoss Eclipse IDE主要支持J2EE的WEB和EJB开发,实则提供ant和xdoclet自动提示{方便功能,q提供Hibernate EJB 3.0 JBoss AOP{开发,内置Jsp~辑器。可实现J2EE模块打包和设定部|Ԍl合JBoss服务器进行调试等?/p>

  安装JBoss Eclipse IDE到Eclipse中有两种方式Q注意Eclipse的插件安装非常注意版本,q是需要非常小心的Q?/p>

  W一U:下蝲安装Q在|址http://www.jboss.org/products/jbosside下蝲

  W二U:配置Eclipse的find and installQ将bookmark http://jboss.sourceforge.net/jbosside/updates

  如果是Eclipse 3.0Q就下蝲支持3.0插gQ如果是Eclipse 3.1Q就下蝲支持3.1Q注意不能是3.1M8 {,后面有M的也不行?/p>

  安装完成后,参考JBoss的开发指南一步步操作卛_Q?/p>

  http://docs.jboss.com/jbosside/tutorial/build/en/html/

  当然Q除了Eclipseq样的开发工P我们q需要事先搭建J2EEq行环境QJBoss+MySQLQ我们这个组合也UCؓEclipse+JBoss+MySQL无敌开源免费J2EE/EJB开发组合?)

  Z辑ֈ熟练开发,xDoclet虽然由Eclipse配置后自动生成,但是有关JNDI调用需要手工写一些xDoclet标签Q?a target="_blank">dq篇文章http://www.devx.com/Java/Article/20578基本了解xDoclet了。剩余的是查xDcolet使用手册Q不q在开发时Q用Ctrl+Space按键可自动提C标{语法?/p>

  在按照JBossIDE开发指南开发这样一个J2EE应用Ӟ有些问题需要自p冻I如没有MANIFEST.MF需要自己创Z个;application.xml中需要手工写正确{。MQ前提需要对WEB或EJB知识有一个了解,知道哪些问题属于J2EE问题Q哪些属于自q_心问题?/p>

  我已l开发了一个Web+EJB的J2EE例程源码?a target="_blank">VIP教程?/a>,其中Session是用LocalQ而非remote。用Local在一台服务器里运行时Q性能比较快?/p>



大鸟 2008-05-30 10:50 发表评论
]]>
Java的数据库q接~程QJDBCQ技?/title><link>http://www.tkk7.com/dunkbird/articles/199356.html</link><dc:creator>大鸟</dc:creator><author>大鸟</author><pubDate>Thu, 08 May 2008 13:36:00 GMT</pubDate><guid>http://www.tkk7.com/dunkbird/articles/199356.html</guid><wfw:comment>http://www.tkk7.com/dunkbird/comments/199356.html</wfw:comment><comments>http://www.tkk7.com/dunkbird/articles/199356.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/dunkbird/comments/commentRss/199356.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/dunkbird/services/trackbacks/199356.html</trackback:ping><description><![CDATA[    只有注册用户d后才能阅读该文?a href='http://www.tkk7.com/dunkbird/articles/199356.html'>阅读全文</a><img src ="http://www.tkk7.com/dunkbird/aggbug/199356.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/dunkbird/" target="_blank">大鸟</a> 2008-05-08 21:36 <a href="http://www.tkk7.com/dunkbird/articles/199356.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA 遍历文ghttp://www.tkk7.com/dunkbird/articles/195940.html大鸟大鸟Fri, 25 Apr 2008 05:17:00 GMThttp://www.tkk7.com/dunkbird/articles/195940.htmlhttp://www.tkk7.com/dunkbird/comments/195940.htmlhttp://www.tkk7.com/dunkbird/articles/195940.html#Feedback0http://www.tkk7.com/dunkbird/comments/commentRss/195940.htmlhttp://www.tkk7.com/dunkbird/services/trackbacks/195940.html阅读全文

大鸟 2008-04-25 13:17 发表评论
]]>
eclipse+tomcat+lomboz的安装配|说?/title><link>http://www.tkk7.com/dunkbird/articles/195169.html</link><dc:creator>大鸟</dc:creator><author>大鸟</author><pubDate>Wed, 23 Apr 2008 09:11:00 GMT</pubDate><guid>http://www.tkk7.com/dunkbird/articles/195169.html</guid><wfw:comment>http://www.tkk7.com/dunkbird/comments/195169.html</wfw:comment><comments>http://www.tkk7.com/dunkbird/articles/195169.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/dunkbird/comments/commentRss/195169.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/dunkbird/services/trackbacks/195169.html</trackback:ping><description><![CDATA[<p>q几天想做这个,按照|上其他兄弟发的文章配置了一下,发现其中不少问题Q按照他们写得文章L配置不成功,最后发C原因Q文章里要求“注意”的地方就是出错的地方Q所以写q篇文章修正一?br /> <br /> 一、Y件下载:<br /> <br /> 注意Q(一?个,一个都不能,很多|友发表的相同文章里只写了需要下载安装tomcat的YӞ而没有写q需要下载eclipse里的tomcat插gQ导致很多网友安装后eclipse里不能正常显CtomcatQ?br /> 1、java<br /> q里使用的是jdk1.4.2?br /> 下蝲地址Q?http://dlc.sun.com/jdk/j2sdk-1_4_2_07-windows-i586-p.exeQ?<br /> 2、tomcat<br /> q里的tomcat的版本是5.0的,安装版或是解压版都是可以的?br /> 下蝲地址Q?http://apache.linuxforum.net/dist/jakarta/tomcat-5/v5.0.28/bin/jakarta-tomcat-5.0.28.exe <br /> <br /> 3、tomcat插g<br /> tomcatPluginV3.zip(下蝲之前需要查看插件是否适合eclipse的版?<br /> 下蝲地址Q?http://www.sysdeo.com/eclipse/tomcatPluginV3.zip <br /> <br /> 4、eclipse<br /> 开发IDE eclipse-SDK-3.0.1-win32.zip<br /> 下蝲地址Q?http://sunsite.informatik.rwth-aachen.de/eclipse/downloads/drops/R-3.0.1-200409161125/download.php?dropFile=eclipse-SDK-3.0.1-win32.zip <br /> 语言?NLpack-eclipse-SDK-3.0.x-win32.zip<br /> 下蝲地址Q?http://sunsite.informatik.rwth-aachen.de/eclipse/downloads/drops/L-3.0.1_Translations-200409161125/NLpack-eclipse-SDK-3.0.x-win32.zip <br /> <br /> 5、lomboz插g<br /> lomboz插g需要下载两个部分,一个是emf环境Q另一个是lomboz插g<br /> 下蝲地址Q?http://eclipse.mirrors.tds.net/tools/emf/downloads/drops/2.0.1/R200409171617/emf-sdo-runtime-2.0.1.zip <br /> 下蝲地址Q?http://download.forge.objectweb.org/lomboz/org.objectweb.lomboz_3.0.1.N20050106.zip <br /> <br /> <br /> 二、Y件安装:<br /> <br /> 1、java安装<br /> q行可执行文件j2sdk-1_4_2_07-windows-i586-p.exeQ?br /> 安装l束后需配置环境变量Q在我的?sh)?>?->高->环境变量->pȝ变量中添加以下环境变?br /> CLASSPATH: %JAVA_HOME%lib;%TOMCAT_HOME%commonlib<br /> JAVA_HOME: c:j2sdk1.4.2<br /> PATH: %SystemRoot%system32;%SystemRoot%;%SystemRoot%System32Wbem;C:Program FilesATI TechnologiesATI Control <br /> Panel;%JAVA_HOME%in;%TOMCAT_HOME%in<br /> <br /> <br /> 2、tomcat安装<br /> <br /> 解压版的直接解压可以了Q然后配|环境变量TOMCAT_HOME = C:Program FilesApache Software FoundationTomcat 5.0Q安装版的要注意的两点,一个是安装完之后tomcat的服务就能够启动的了Q但是还是要配置TOMCAT_HOMEQ第二个是需要查看一下安装程序是不是把tomcat服务注册成ؓwindows的启动服务,需要到“服务”里查看,如果有这个选项把它设|ؓ手动启动Qƈ且先停止q个服务?br /> [试]Q用startup.bat命oQ服务正常启动之后,ie览器里输入<br /> http://localhost:8080/ 如果出现正常的小猫页面,那就应该没有问题了?br /> <br /> 3、eclipse安装<br /> eclipse的安装很单,只要解压Q然后把eclipse目录复制到盘W下可以了Q启动的时候,pȝ会自动寻找jvmQ当然可以再以后配置Q但是好像是必须先安装jdk。我q里是放在D:eclipse?br /> <br /> 4、tomcat插g安装Qemf插g安装Qlomboz插g安装Q?br /> tomcatPluginV3.zip解压后将文g夹com.sysdeo.eclipse.tomcat_3.0.0拯到D:eclipseplugins<br /> emf插g和lomboz插g解压后将feature和plugins目录拯?D:eclipse 卛_<br /> <br /> 三、eclipse配置<br /> <br /> 配置Java <br /> 在Eclipse中点击windows->preferences,在出现的H口中选择java->Installed JRES,q时可以在右边的H口中看到己l有一目Q名字ؓj2re1.4.2_04。我们再在这里点d面的"Add"按钮Q增加一个JREQ在出现的对话框中输入: <br /> JRE Type: Standard VM <br /> JRE name: 可以随意输入一个名?<br /> JRE home directory:q里选择你的JDK的安装目录,好比你的JDK装在F:J2SDKQ那么这里就是选择F:J2SDKq个目录?<br /> 其它的可以都不管Q点击OK新增了一个JRE了?<br /> <br /> q里修改完了之后回到preferences对话框中的Java->Build Pathq一,点击Build Path后,在右面的面板中我们选择Source and output folder下面的Foldersq一,而两个Source folder name和Output folder name的值我们不修改Q保存ؓpȝ默认|但是下面的As JRE library use:我们要选择为JRE_LIB variableq一,不能为默认值JRE containerQ最后点M面的Apply按钮。这一步千万不要忘CQ不然刚才的都是白做了?<br /> <br /> 4Q设|Lomboz <br /> 在PreferencesH口中选定LombozQ然后把双面板中的JDK Tools.jar选择Z安装好JDK后,在JAVA_HOMELIB目录下面的tools.jar文g可以了Q一定不要搞错了Q如果你的JDK是安装在F:J2SDK下面Q那么这里的值就应该是F:J2SDKlib ools.jarQ是其它的都不对。其它的保持为默认倹{?<br /> 接着把Lombozq一展开Q关键要讄的地Ҏ(gu)Server Definitionsq一,另外两项Code Generation和JSP Editor可以不管。展开Lomboz的Server Definitions后,在Server types里选择Apache Tomcat v4.1.0(q是按照我的机器上的配置q行讄的,如果你安装的是其它版本的TOMCATQ你p选择对应的选项)Q主要设|如下: <br /> Properties <br /> Application Server Directory:q是我的TOMCAT 4.1.30的安装目录,我装在F: omcat下面Q所以它的值就是F:/tomcat <br /> Address:127.0.0.1 <br /> PortQ?0(因ؓ我在TOMCAT中把8080改ؓ80了,所以这里就?0了,以你的TOMCAT的监听端口ؓ? <br /> Classpath Variable Name: TOMCAT_HOME(可以修改成其它的字符? <br /> Classpath Variable: F:/tomcat(TOMCAT的安装目? <br /> 然后点击Apply按钮?<br /> Server Classpath: <br /> JDK_TOOLS <br /> ${classPathVariableName}/bin/bootstrap.jar <br /> ${classPathVariableName}/common/servlet.jar <br /> ${classPathVariableName}/common/jasper-runtime.jar <br /> 然后点击Apply按钮?<br /> <br /> Client Classpath: <br /> q里为空Q什么也没有?<br /> <br /> Project Classpath: <br /> JDK_TOOLS <br /> ${classPathVariableName}/bin/bootstrap.jar <br /> ${classPathVariableName}/common/servlet.jar <br /> ${classPathVariableName}/common/jasper-runtime.jar <br /> 然后点击Apply按钮?<br /> q里?Server Classpath:和Project Classpath:我设|的是一L(fng)?br /> <br /> 注意Q(以上配置 Server Classpath?Project ClasspathӞ可能因ؓtomcat版本的不同?.jar的文件位|也不同Q如果时tomcat5.x版的 ,?{classPathVariableName}/common/servlet.jar ?${classPathVariableName}/common/jasper-runtime.jar 应ؓ${classPathVariableName}/common/lib/servlet-api.jar ?${classPathVariableName}/common/lib/jasper-runtime.jar Q比4.x版的多了一层lib目录。) <br /> 5Q修Ҏ(gu)?<br /> 把Eclipse_homepluginscom.objectlearn.jdt.j2ee_3.0.1servers 下面对应的server文g打开Q比如我安装的TOMCAT?.1.30版的Q那么就把tomcat410.serverq个文g打开Q把里面?Djava.endorsed.dirs="${serverRootDirectory}/bin;${serverRootDirectory}/common/endorsed" <br /> Ҏ(gu) <br /> -Djava.endorsed.dirs="${serverRootDirectory}/common/endorsed" <br /> 一共有两处Q都要修改,修改完之后保存,退出,重新启动EclipseQ这一步很重要Q一定要做,不然的话你在Lomboz中启动TOMCAT的时候会再现很多莫明其妙的异常的<br /> 注意Q如果用的是tomcat5.x版的可能没有以上东西要改 <br /> <br /> 6Q调出Lomboz各个菜单 <br /> 启动EclipseQ然后点击windows->Customize Perspective,在出现的对话框中的Shortcuts面中首先选中左边面板中的Lomboz J2EE WizardsQ这时右边的面板中会出现很多选项的,同时也把它们各项前面的对钩打上?<br /> 然后在这个Shortcuts面板中改变Submenus:的|选择Show ViewQ接着在出现的面板的左辚w选中Lomboz J2EEQ同时也要把它前面的Ҏ(gu)中打上对钩?<br /> 最后是更换Customize Perspective对话框中的面板到Commandsq一: <br /> 在Commandsq一中选定Lomboz Actions同时也把它们各项前面的对钩打上?<br /> 所有的讄完毕?<br /> q样一切做完之后,Eclipse和Lomboz的环境就配置好了Q你可以q行开发各U程序了?<br /> 个h体会Q?<br /> 可能在第5步中有些机器上可以不做,因ؓ有不同的TOMCAT版本Q不q我机器一定要改了才行Q不然的话是不能正常启动TOMCAT的。我个h使用TOMCAT4.1.30版的Q是因ؓ我觉得这个版本的比较?yu),q行h也比较快Q比5.0以上版本的要快多了,而且也要相对E_一?个h看法Q不代表其它人的)Q还有就是对于Eclipse 3.0的,可以参照上面的说明进行配|,基本上也可以行得通的Q没有什么比较大的问题?strong></strong></p> <img src ="http://www.tkk7.com/dunkbird/aggbug/195169.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/dunkbird/" target="_blank">大鸟</a> 2008-04-23 17:11 <a href="http://www.tkk7.com/dunkbird/articles/195169.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>你是否了解这些常被问L(fng)问题- -javahttp://www.tkk7.com/dunkbird/articles/195021.html大鸟大鸟Wed, 23 Apr 2008 04:45:00 GMThttp://www.tkk7.com/dunkbird/articles/195021.htmlhttp://www.tkk7.com/dunkbird/comments/195021.htmlhttp://www.tkk7.com/dunkbird/articles/195021.html#Feedback0http://www.tkk7.com/dunkbird/comments/commentRss/195021.htmlhttp://www.tkk7.com/dunkbird/services/trackbacks/195021.html阅读全文

大鸟 2008-04-23 12:45 发表评论
]]>
如何才能依次逐个M个文件夹中的所有文? http://www.tkk7.com/dunkbird/articles/195016.html大鸟大鸟Wed, 23 Apr 2008 04:39:00 GMThttp://www.tkk7.com/dunkbird/articles/195016.htmlhttp://www.tkk7.com/dunkbird/comments/195016.htmlhttp://www.tkk7.com/dunkbird/articles/195016.html#Feedback0http://www.tkk7.com/dunkbird/comments/commentRss/195016.htmlhttp://www.tkk7.com/dunkbird/services/trackbacks/195016.html阅读全文

大鸟 2008-04-23 12:39 发表评论
]]>
j2ee的学?fn)笔讎ͼ?Q{http://www.tkk7.com/dunkbird/articles/195014.html大鸟大鸟Wed, 23 Apr 2008 04:37:00 GMThttp://www.tkk7.com/dunkbird/articles/195014.htmlhttp://www.tkk7.com/dunkbird/comments/195014.htmlhttp://www.tkk7.com/dunkbird/articles/195014.html#Feedback0http://www.tkk7.com/dunkbird/comments/commentRss/195014.htmlhttp://www.tkk7.com/dunkbird/services/trackbacks/195014.html阅读全文

大鸟 2008-04-23 12:37 发表评论
]]>
j2ee学习(fn)W记Q{Q?/title><link>http://www.tkk7.com/dunkbird/articles/195004.html</link><dc:creator>大鸟</dc:creator><author>大鸟</author><pubDate>Wed, 23 Apr 2008 04:27:00 GMT</pubDate><guid>http://www.tkk7.com/dunkbird/articles/195004.html</guid><wfw:comment>http://www.tkk7.com/dunkbird/comments/195004.html</wfw:comment><comments>http://www.tkk7.com/dunkbird/articles/195004.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.tkk7.com/dunkbird/comments/commentRss/195004.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/dunkbird/services/trackbacks/195004.html</trackback:ping><description><![CDATA[    只有注册用户d后才能阅读该文?a href='http://www.tkk7.com/dunkbird/articles/195004.html'>阅读全文</a><img src ="http://www.tkk7.com/dunkbird/aggbug/195004.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/dunkbird/" target="_blank">大鸟</a> 2008-04-23 12:27 <a href="http://www.tkk7.com/dunkbird/articles/195004.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://zc-zk.com" target="_blank">av</a>| <a href="http://www-3499.com" target="_blank">þþƷһԡ</a>| <a href="http://mychjp.com" target="_blank">AVһ</a>| <a href="http://w9366.com" target="_blank">˾Ʒҹapp</a>| <a href="http://www-79983.com" target="_blank">AV뾫Ʒɫҹ߹ۿ</a>| <a href="http://rimcn.com" target="_blank">ԺȫƵƵ</a>| <a href="http://vvv75.com" target="_blank">AVֻ߹ۿ</a>| <a href="http://milbolg.com" target="_blank">þһѲ</a>| <a href="http://yy468.com" target="_blank">A߲</a>| <a href="http://haha02.com" target="_blank">þþþþþ99Ʒѹۿ</a>| <a href="http://56kaifa.com" target="_blank">޾Ʒۿ91</a>| <a href="http://717795.com" target="_blank">ѿƵijAPP</a>| <a href="http://023439.com" target="_blank">ߵӰ㶮</a>| <a href="http://26uuyy.com" target="_blank">ֳִִֺƵ</a>| <a href="http://3y0r.com" target="_blank">ձVAҹߵӰ</a>| <a href="http://612662.com" target="_blank">Ļѵַվ</a>| <a href="http://bj-tkld.com" target="_blank">һa</a>| <a href="http://njjngs.com" target="_blank">һ͵Ů</a>| <a href="http://billtsssrvp.com" target="_blank">һëƬ</a>| <a href="http://aplus178.com" target="_blank">avһ߲</a>| <a href="http://ebhqd.com" target="_blank">ҹavƵ</a>| <a href="http://7788mgqb.com" target="_blank">2022ѹƷ</a>| <a href="http://zjpcyh.com" target="_blank">޹ۺһ</a>| <a href="http://liulian88.com" target="_blank">99ee6ȾþѾƷ6</a>| <a href="http://ebuy668.com" target="_blank">þþƷAVþþ</a>| <a href="http://438266.com" target="_blank">ѹۿ˳վ</a>| <a href="http://rdccc.com" target="_blank">ھƷһëƬѿ</a>| <a href="http://kph37.com" target="_blank">޾Ʒ͵Բ</a>| <a href="http://gzmandala.com" target="_blank">2020</a>| <a href="http://666mou.com" target="_blank">ձһ߹ۿ </a>| <a href="http://obtainfo.com" target="_blank">͵ͼƬ</a>| <a href="http://144446.com" target="_blank">ڵƵ</a>| <a href="http://zjtuntex.com" target="_blank">aһëƬѸ</a>| <a href="http://0917xzb.com" target="_blank">޾Ʒ456߲</a>| <a href="http://hmjx-tape.com" target="_blank">ѹۿ</a>| <a href="http://by22877.com" target="_blank">99REþþƷﶼǾƷ</a>| <a href="http://milbolg.com" target="_blank">޹avһؼ</a>| <a href="http://bii59.com" target="_blank">þþþһƷ޹ۺAV</a>| <a href="http://www-554949.com" target="_blank">þþþþҹƷƷ</a>| <a href="http://laosanqq.com" target="_blank">A벥ëƬһ avavavëƬ </a>| <a href="http://600c81.com" target="_blank">100018վ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>