??xml version="1.0" encoding="utf-8" standalone="yes"?>
ear下允许jar的变?br />
web-inf/lib 下不允许jar的变?br />
其变体简z的实质是web-inf/classes
]]>
Java本n是一U设计的非常单,非常_y的语aQ所以Java背后的原理也很简单,归结h是两点Q?
1、JVM的内存管?
理解了这一点,所有和对象相关的问题统l都能解?
2、JVM Class Loader
理解了这一点,所有和Java相关的配|问题,包括各种App Server的配|,应用的发布问题统l都能解?
|----- EJB Class Loader
|----- Web App Class Loader
如果在App Class LoaderU别配置Q是全局可见的?br />
如果打包在EJB里面Q那么就不会(x)影响到Web
ApplicationQ反之亦Ӟ如果你在WEB-INF下面攄HibernateQ也不会(x)影响到EJB?br />
攑֜EJB Class
Loader或者放在Web App Class LoaderU别主要是在局部范围内有效Q不影响到其它的应用?
Q?strong>QmeQ这里是说ClassLoader都有一个加载边界#Q?/span>
试想Q如果在一个Weblogic上面配置多个虚拟域,你用www.bruce.com域名Q开发你的网站,我?
www.fankai.com开发我的网站,那么当然不希望我们的Hibernate怺q扰Q所以就可以攑֜ EJB Class
LoaderU别来配|Hibernate?
q一步阐qC下EJB Class Loader的问题:(x)
先再ơ强调一下,Hibernate和EJBQ和App
Server不存在兼Ҏ(gu)问题,他们本来是不相关的东西Q就好像JDBCQ相信没有h?x)认为JDBC和EJB不兼容吧QHibernate也是一P?
只和JDBC驱动Q和数据库有兼容性问题,而和EJBQ和App
Server完全是不搭界的两回事。凡是认为Hibernate和EJB不兼容的人,其实是都是因为对EJB学习(fn)的不到家Q把责Q推到Hibernate
w上了?
我前面的帖子提到qClass Loader的层ơ,q里不重复了QM我们先来看看Class Loader的作用范_(d)(x)
Q#me: BootStrap Class Loader?x)加载ExtClassLoader, q设|其parent为null
然后BootStrap Class Loader?x)加载AppClassLoader,q设|其parent为ExtClassLoader
然后ExtClassLoader加蝲QAppClassLoader再加载#Q?br />
>>>>> load JRE"lib"rt.jar, sunrsasign.jar, charsets.jar, jce.jar, jsse.jar, plugin.jar
Ext Class Loader:
>>>>>load JRE"lib"ext目录下的库文? load JRE"classes目录下的c?/span>
App Class Loader:
>>>>>load CLASSPATH变量指定路径下的c?br />
以上的load路径都是写死在JVM的C++源代码里面的Q不能改变,详细误王森的《Java深度历险?
在一个特定的App Server上,Class Loader?x)l向下承,l承的层ơ会(x)Ҏ(gu)不同的App Server有所不同Q但是肯定不?x)变的就是?x)
>>>>>l承自App Class LoaderQ承层ơ根据App Server有所不同Q?br />
>>>>>一个EJB Class Loader它的load Class的范围仅限于JAR或者EAR范围之内?/span>
Web App Class Loader:
>>>>>l承自App Class LoaderQ承层ơ根据App Server有所不同Q?br />
>>>>>一个Web App Class Loader:它的load Class的范围在 WEB-INF"lib下的库文件和W(xu)EB-INF"classes目录下的class文g?/span>
Web App Class Loader很好理解Q大家毕竟用的很多,App Server上的一个Web
Application?x)创Z个Web App Class Loader的实例去负责load
classQ所以如果你惌Hibernate只在q个Web Application内生效,把它攑ֈWEB-INF"lib下去好了?
如果你把Hibernate攑ֈ了CLASSPATH变量指定的\径下Q而你在WEB-INF"lib也放了一份,那么Web App
Class
Loader׃load范围所限,它会(x)首先扑ֈWEB-INF"lib下的那䆾HibernateQ按照它的配|来初始化Hibernate?
如果你把Hibernate攑ֈ了CLASSPATH变量指定的\径下Q但你在WEB-INF"lib什么都没有放,那么Web App
Class Loader׃load范围所限,它根本什么都找不刎ͼ于是它把load Hibernate的责Ml上一U的Class
LoaderQ这L(fng)到App Class LoaderQ它扑ֈ了HibernateQ按照它的配|来初始化Hibernate?
EJB Class LoaderE微复杂一点,不那么容易理?/span>?strong>App Server?x)针?gu)一个EJB包文件创Z个EJB Class Loader的实?/strong>Q例如:(x)
HelloBruce.jar
当你把这两个jar发布到App Server上以后,?x)创Z个EJB Class Loader的实例,分别去loadq两个EJB包,比如_(d)(x)
说到q里Q?span style="color: red;">我相信大家应该已l明白ؓ(f)什么EJB规范不允许EJB有IO操作了吧Q因为EJB Class LoaderҎ(gu)找不到jar包之外的文gQ!Q?
Q#me:q里是我疑问最大的地方Q也是测试验证的地方Q)
如果现在你想实现HelloRobbin.jar和HelloBruce.jar?span style="background-color: rgb(239, 255, 120);">互相调用Q那么该怎么办?他们使用了不同的EJB Class LoaderQ相互之间是找不到对方的。解军_法就是用EAR?
现在假设HelloRobbin.jar和HelloBruce.jar都用了HibernateQ看看该怎么打包和发布:(x)
|------ HelloRobbin.jar
|------ HelloBruce.jar
|------ Hibernate2.jar
|------ pojo.jar (定义所有的持久对象和hbm文g的jar?
|------ cglib-asm.jar
|------ commons-beanutils.jar
|------ commons-collections.jar
|------ commons-lang.jar
|------ commons-logging.jar
|------ dom4j.jar
|------ odmg.jar
|------ log4j.jar
|------ jcs.jar
|------ hibernate.properties
|------ log4j.properties
|------ cache.ccf
|------ META-INF"application.xml (J2EE规范的要求,定义EAR包里面包括了哪几个EJB)
除此之外Q按照EJB规范要求QHelloRobbin.jar和HelloBruce.jarq必L用jar包之外的cd的名Uͼq需要在jar包的manifest文g中定义:(x)
|------ META-INF"MANIFEST.MF
MANIFEST.MF中必d括如下一行:(x)
commons-logging.jar dom4j.jar jcs.jar odmg.jar jcs.jar pojo.jar
q样O(jin)K了,当把HelloEJB.ear发布到App Server上以后,App Server创徏一个EJB Class
Loader实例load
EAR包里面的EJBQ再Ҏ(gu)EJB的jar包里面的MANIFEST.MF指出的Class-Pathd扄应的jar包之外的cd?
所以一个EAR包有点类g个Web ApplicationQEJB Class
Loader的load范围也就是EAR范围之内Q它load不到EAR之外的文件。除非把Hibernate定义到CLASSPATH指定的\径下Q在
q种情况下,EJB Class Loader找不到HibernateQ只能交l上一U的Class LoaderQ最后由App Class
Loader扑ֈHibernateQ进行初始化?
没有写完Ql说...
׃EARq样load Class规则Q假设Robbin和Bruce都在同一个Weblogic上运行自q|站Q而我们都不希望自qE序里面的Hibernate配置被对方的搞ؕ掉,那么我们可以这h做:(x)
Robbin.ear
|-------- robbin.war (把Web Application打包)
|-------- robbin.jar (把开发的EJB打包Q?br />
|-------- Hibernate2.jar
..
|-------- META-INF"application.xml
Bruce's Website:
Bruce.ear
|-------- bruce.war (把Web Application打包)
|-------- bruce.jar (把开发的EJB打包Q?br />
|-------- Hibernate2.jar
..
|-------- META-INF"application.xml
q样在同一个App Server上运行,可以互怸q扰?br />
Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q=Q?br />
xQ这个是引文Q外加了部分个h的解释?br />
其中针对如下的话Q?br />
EJB模型不推荐或者禁止在EJBlg中读取文?...
Z么不允许d文g呢?是否真的找不到呢Q?br />
我采用了两种方式Q?br />
${Class_Name}.class.getClassLoader().getResourceAsStream("${file}");
file路径方式Q?br />
一U方式采用直接的l对路径
一U方式采用相对于ear包的Qjar包内
Q方式二Q?br />
new File(${file})
file路径采用l对路径
方式一采用l对路径的文件方式,貌似q回是nullQ记录有Ҏ(gu)p了Q?br />
方式二采用绝对\径,l对没有问题
我现在想Qƈ不是真的不能讉K外部资源Q而是其设计就是ؓ(f)了把classloaser的界限限制在jar包内或者ear内,而不怺q扰Q因而在其规范中是止或者不推荐d文g的方式了?br />
]]>
ClassLoader专题Q二Q:(x)从Servlet容器看ClassLoader机制的妙?/a>
ClassLoader专题Q三Q:(x)引文
ClassLoader专题Q四Q:(x)部vear包出错引发的ClassLoader的思?/a>
应用服务器常常包含多个容器,当前使用的是JBossQ在部vear?/strong>的时候,遇到了一些比较有意思的问题Q遂随着不断的推Ԍ从而解决了问题Q也对classloader在应用服务器如JBoss中有了一点的推测Q不当之处请光顾的朋友指出)?br />
试环境QJBoss4.0.5.GA 、Gentoo Linux?spring、ejbQ?strong>ear工程Q?br />
1Q用ant打包脚本的疏忽,把struts action的class同时攑֜?{ear_file}/${jar_file} ?{ear_file}/${war_file}/WEB-INF/{lib}/${jar_file}
U正之后Q再ơ修改了struts action的实现类Q后者确实不断地更新Q但是始l未被执行,而执行的L前?br />
2Qant打包Q把${xml_config_file}攑֜?{ear_file}/${jar_file} ?{ear_file}/${war_file}/WEB-INF/classes/${xml_config_file}
之后做了如下的测试:(x)
21Q前者不变,更新后者,l果Q取新增加的物g出错
22Q移除前者,更新后者,l果Q可以取到新增加的物?br />
23Q保持前者,新物件的配置作ؓ(f)一个新的文Ӟ同时也放在后者的位置Q结果:(x)可以取到新增加的物g?br />
3Q通过IoC注入配置文g的位|,然后d配置文g的内?未用Spring的解析方法,而是自己实现解析)Q?br />
注入xml位置的配|如下(_体处)Q?br />
<property name="dataExtractDao"><ref bean="demo.dataExtractDao"/></property>
<property name="markExtractedDao"><ref bean="demo.markExtractedDao"/></property>
<property name="errorsPath" value="/home/cuiyi/demo/Errors/"/>
<property name="invoicesPath" value="/home/cuiyi/demo/Invoices/"/>
<property name="archivesPath" value="/home/cuiyi/demo/Archives/"/>
<property name="sqlPath" value="x.war/WEB-INF/classes/xyz_sql.xml"/>
</bean>
xyz_sql.xml的真实位|在/home/jboss/jboss-4.0.5.GA/server/xyz/deploy/x.ear/x.war/WEB-INF/classes/xyz_sql.xml
注入了sqlPath后,交给了一个工L(fng)来解析,q个工具cL在表现层Q即打包到war里,代码cM如下
SAXReader reader = new SAXReader();
//Print Code
InputStream in = SqlReaderHelper.class.getClassLoader().getResourceAsStream(fileName);
Document document = reader.read(in);
return document;
}
在getRootDocumentҎ(gu)的Print Code处,增加如下打印语句Q?br />
System.out.println(SqlReaderHelper.class.getClassLoader().getResource(""));
System.out.println(SqlReaderHelper.class.getClassLoader().getResource("/test.xml"));
System.out.println(SqlReaderHelper.class.getClassLoader().getResource("/../test.xml"));
System.out.println(SqlReaderHelper.class.getClassLoader().getResource("../test.xml"));
System.out.println(Thread.currentThread().getContextClassLoader().getResource("/"));
System.out.println(Thread.currentThread().getContextClassLoader().getResource(""));
System.out.println(SqlReaderHelper.class.getClass().getClassLoader().getResource(""));
得到的输出结果(外加了打印语句的本n描述Q?br />
17:47:18,214 INFO [STDOUT] -------->>>>>>>>SqlReaderHelper.class.getClassLoader().getResource("") : file:/home/jboss/jboss-4.0.5.GA/server/xyz/deploy/x.ear/
17:47:18,222 INFO [STDOUT] -------->>>>>>>>SqlReaderHelper.class.getClassLoader().getResource("/test.xml") : null
17:47:18,231 INFO [STDOUT] -------->>>>>>>>SqlReaderHelper.class.getClassLoader().getResource("/../test.xml") : null
17:47:18,241 INFO [STDOUT] -------->>>>>>>>SqlReaderHelper.class.getClassLoader().getResource("../test.xml") : null
17:47:18,241 INFO [STDOUT]-------->>>>>>>>Thread.currentThread().getContextClassLoader().getResource("/"):null
17:47:18,242 INFO [STDOUT]-------->>>>>>>>Thread.currentThread().getContextClassLoader().getResource(""):file:/home/jboss/jboss-4.0.5.GA/server/xyz/deploy/x.ear/
执行?span style="color: #000000;">System.out.println(Thread.currentThread().getContextClassLoader().getResource("")); 出错
q在getRootDocumentҎ(gu)的Print Code处,增加如下打印语句Q?br />
System.out.println(SqlReaderHelper.class.getClassLoader().getResource(""));
System.out.println(SqlReaderHelper.class.getClassLoader().getResource("/test.jar"));
System.out.println(SqlReaderHelper.class.getClassLoader().getResource("/../test.jar"));
System.out.println(SqlReaderHelper.class.getClassLoader().getResource("../test.jar"));
System.out.println(SqlReaderHelper.class.getClassLoader().getResource("test.jar"));
System.out.println(Thread.currentThread().getContextClassLoader().getResource("/"));
System.out.println(Thread.currentThread().getContextClassLoader().getResource(""));
System.out.println(SqlReaderHelper.class.getClassLoader().getResource(fileName));
17:57:16,900 INFO [STDOUT] -------->>>>>>>SqlReaderHelper.class.getClassLoader().getResource("") : file:/home/jboss/jboss-4.0.5.GA/server/xyz/deploy/x.ear/
17:57:16,909 INFO [STDOUT] -------->>>>>>>SqlReaderHelper.class.getClassLoader().getResource("/test.jar") : null
17:57:16,918 INFO [STDOUT] -------->>>>>>>SqlReaderHelper.class.getClassLoader().getResource("/../test.jar") : null
17:57:16,926 INFO [STDOUT] -------->>>>>>>SqlReaderHelper.class.getClassLoader().getResource("../test.jar") : null
17:57:16,926 INFO [STDOUT] -------->>>>>>>SqlReaderHelper.class.getClassLoader().getResource("test.jar") : file:/home/jboss/jboss-4.0.5.GA/server/xyz/deploy/x.ear/test.jar
17:57:16,927 INFO [STDOUT]-------->>>>>>>Thread.currentThread().getContextClassLoader().getResource("/"):null
17:57:16,927 INFO [STDOUT]------->>>>>>>Thread.currentThread().getContextClassLoader().getResource(""):file:/home/jboss/jboss-4.0.5.GA/server/xyz/deploy/x.ear/
17:57:16,927 INFO [STDOUT] -------->>>>>>>SqlReaderHelper.class.getClassLoader().getResource("fileName") : file:/home/jboss/jboss-4.0.5.GA/server/xyz/deploy/x.ear/cxc3.war/WEB-INF/classes/cxc2sap_sql.xml
通过上述描述Q可以简单的得出一些推?/span>Q?br />
?Q?Q?/span>
在应用服务器?/span>JBoss中,加蝲${ear_file}/${jar_file}的EJB容器 ?加蝲${ear_file}/${war_file}的Web容器间存在一定的关系Q根据ClassLoader的加载机Ӟ(x)当当前类加蝲器需要加载一个类的时候,首先h父的类加蝲器加载,如果父加蝲器无法找到要加蝲的类Q每个加载器仅仅在自己本w的classpathL要加载的c)Q才由当前类加蝲器来加蝲Q如果加载不到就报错?br />
Ҏ(gu)q个Q可认ؓ(f)EJB容器的ClassLoader起了Web容器的父UClassLoader的作用,卻I(x)h加蝲一个action classӞ当前cd载器是web容器Q但是web容器的ClassLoader委托其父U加载器来加载,l果其父亲加载ƈ加蝲成功了,所以不再加载本来正的${war_file}/WEB-INF/lib or ${war_file}/WEB-INF/classes下的真正的类?br />
?Q?/span>
q些输出信息则更充分的证明了当?{Class_name}.class.getClassLoader()的时候,真正起作用的cd载器便是父cd载器Q即使EJB容器的ClassLoaderQ从而得到的当前classpath?{ear_file}的\径?br />
回想q去l历Q?/span>
Zq些实验Q记得曾l遇到这L(fng)错误Q把struts.jar也放在了${ear_file}之下Q运行报错误?br />
原因依然是类加蝲器的两个基本原理Q?br />
1Q加载的委托机制Q见上面的分?br />
2Q当一个类被某一个ClassLoader加蝲后,与其相关的类都由同一个ClassLoader加蝲
于是得出如下l论QEJB容器加蝲了struts.jarQ当web容器的ClassLoader加蝲自己的action class的实现类的时候,需要Action基类Q但是根据默认的加蝲原理Q关联的cd该由同一个类加蝲器完成,现在Action基类被父U的加蝲器加载(相对于当前)QAction的实现类在当前的cd载器Q故此发生错误?br />
]]>代码
二、属性文?br />
文g一
PAYMENT AFTER DELIVERY=PAYMENT AFTER DELIVERY
PAYMENT BEFORE COLLECTION=PAYMENT BEFORE COLLECTION
PAYMENT BEFORE COLLECTION-SHELL=PAYMENT BEFORE COLLECTION
PAYMENT BEFORE DELIVERY=PAYMENT BEFORE DELIVERY
文g?br />
property file with blank in key part
三、输?br />
文g一的输?br />
Property--->>>>PAYMENT Value--->>>>BEFORE DELIVERY=PAYMENT BEFORE DELIVERY
文g二的输出
output of key having blank
四、结?br />
弃用XMLW一ơ启用属性文Ӟ是一个月前,于q度Q遂以Map代码中设|之Q?br />
今看Properties Editor Plugin for Eclipse; 获得颜色提示 H然莯Q庆之记录之?
]]>
private List<String> generateList() {
String[] figures = new String[]{"1", "2", "3", "4", "5", "6", "7", "8", "9"};
List<String> list = new ArrayList<String>();
for (String figure : figures)
list.add(figure);
return list;
}
public void test1() {
List<String> loads = generateList();
if (null != loads && !loads.isEmpty()) {
for (String load : loads) {
System.out.println(load);
if (Integer.valueOf(load).intValue() ==3){
loads.remove(load); System.out.println("====" + loads.get(2));
}
}
System.out.println("size" + loads.size());
}
}
public static void main(String[] args) {
DynamicRemove test = new DynamicRemove();
test.test1();
}
输出为:(x)
你答对了?/span>
q样呢?
嘿嘿Q是q样?/span>
{案
]]>
]]>
[q程]
是程序的一ơ执行,
是资源分配的单位[x占CPU的调度单位]Q所有与该进E相关的资源Q打印机、内存)都被登记在PCB中,
拥有完整的虚拟地址I间
[U程]
它属于一个进E?br />与资源分配无?br />与进E内的其它线E一起共享该q程的资?br />
W二局
[调度]
q程调度Ӟ不同q程拥有不同虚地址I间Q?br />同一q程内的不同U程׃n同一地址I间
W三局
[切换]
q程切换Ӟ涉及(qing)资源指针的保存和地址I间的变化等问题Q即切换q程上下文)
U程切换Ӟ不涉?qing)资源信息的保存和地址I间的变化等问题Q减了pȝ的开销
]]>
本篇只是强化和复?fn)?x)
1 多态只针对非finalҎ(gu)Q?br /> 不针对变量、finalҎ(gu)
2Ҏ(gu)[非final]是运行时对应对象
变量、fianl是编译期间对应对?br />
3多态只能调用父cM有的Ҏ(gu)(向上扩展?
不能调用父类中没有的Ҏ(gu)Q?br /> 不能调用子类中扩展父c[not overridding]Ҏ(gu)
4多态定义:(x)指的是用同一个实现接口,以实C同的对象实例
多态好处:(x)多态让E序依赖接口或者抽象类Q而不是具体类
ClassLoader 专题Q一Q:(x) ClassLoader 基础
ClassLoader 专题Q二Q:(x)?/span> Servlet 容器?/span> ClassLoader 机制的妙?/span>
ClassLoader专题Q三Q:(x)引文
JVM启动Q会(x)形成3个类加蝲器组成的初始化加载器层次l构Q?br>bootstap classloader Q加载核心类Q?
||
extension classloaderQ加载ext(目录)Q即java.ext.dirs()Q?br> ||
system classloader Q加?classpath或者java.class.path或者CLASSPATHQ?/p>
ClassLoader机制Q?br>aQ全盘负责:(x)一个classloader加蝲一个class后,q个class所引用或者依赖的cMp个classloader载入Q除非显C的用另一个classloader载入
bQ委托机Ӟ(x)先由父加载器加蝲Q除非父加蝲器找不到时才从自qc\径中d?br>cQCache机制Qclassloader采用~存机制Q即先查cacheQ若cache中保存了q个classq接返回;若无Q才从文件读取和转化为classq放入cache
ClassLoader加蝲c顺序:(x)
1Q检查cache是否有该c:(x)
11Q若有直接返?br> 12Q若无,h父类加蝲
121) 若无?则从bootstap classloader加蝲
2Q加载:(x)
21Q寻找class文gQ丛与此classloader相关的类路径中寻找)
22Q从文g载入class
23Q找不到则抛出ClassNotFoundeException
3Q扩展:(x)
记蝲时即2Q,覆写findClass可以实现自己的蝲入策?br> 记蝲时即2Q,覆写loadClass来实现自q载入q程
如何实现q行时动态蝲入与更新
本质Q只要动态改cL索\径和清除classloader的cache已蝲入的classok
做法Q?br>1Q承ClassLoaderQ覆写loadClassҎ(gu)Q动态寻找class文g
2Q只要重C用一个新的类搜烦路径来new一个classloader可以,q样既更Ccȝ搜烦路径以便来蝲入新的classQ也更新生成了一个空白的cache
classloader载入的方?br>1QPre-loading 预先载入Q蝲入基c?br>2Qload-on-demand 按需求蝲?/p>
JDK为啥有两个JREQ?br>JDK中jre是运行java本n的程序,如javac
ProgramFileQ默认安装)中jre是运行用L(fng)写的javaE序
要实现排序功?一般有两种途径,q里对基本类型不适用,基本cd一般有Arrays中的静态方?
1.对象本n实现Comparable接口,那么该类的实例就是可以排序的.
有关Comparable: http://blog.csdn.net/treeroot/archive/2004/09/09/99613.aspx
只要实现了Comparable接口,可以调用Collections的sortҎ(gu)寚w合中的元素排?
2.指定一个Comparator,也就是实CComparator的类的一个实?
但是Java本n只提供了一个Comparator的实?是Collections.reverseOrder().
该方法返回的是一个已l实CComparable接口的反?
看一下Comparator的全部内?
public interface Comparator {
int compare(Object o1, Object o2);
boolean equals(Object obj);
}
定义了两个方?其实我们一般都只需要实现compareҎ(gu)p?因ؓ(f)c都是默认从Objectl承
所以会(x)使用Object的equalsҎ(gu).
Comparator一般都作ؓ(f)一个匿名类出现,对于没有实现Comparable的对象的集合,排序的时?br />需要指定一个Comparator.
q里举例说明
对于实现了Comparable的类我们q最单的Integer
List list=new ArrayList();
list.add(new Integer(3));
list.add(new Integer(53));
list.add(new Integer(34));
Collections.sort(list);
对于没有实现Comparable?我们qObject,按照hashCode大小来排?
List list= new ArrayList();
list.add(new Object());
list.add(new Object());
list.add(new Object());
Collections.sort(list,new Comparator(){ public int compare(Object o1, Object o2){
return (o1.hashCode()-o2.hashCode());
});
ClassLoader 专题Q二Q:(x)?/span> Servlet 容器?/span> ClassLoader 机制的妙?/span>
ClassLoader专题Q三Q:(x)引文
classloader有啥妙用Q?Q?
q个问题得从自定义的classloaderw上_(d)那自定义classloader~由是什么呢Q?br>告诉你:(x)大多是因为编译时无法预知q行旉要哪些类Q特别是app serverQ因此自定义classloaderQ运行时指定路径Q来加蝲q个路径下的class
Ҏ(gu)说明
Ҏ(gu)说明1Q如果没有特D指定,用户自定义的classloader都把system classloader作ؓ(f)它的父加载器
Ҏ(gu)说明2Qjvm认ؓ(f)不同的classloade载入相同名字的class是不同的Q即使从同一个class文g载入
classloader有啥妙用Q?Q?
看到Ҏ(gu)说明2Q你或许׃(x)感觉疑惑或者不爽;啥概念?
以servlet、ejb{容器来剖析q个问题Q?/p>
接口或者基cL入classpath <---------system classloader
执行Ӟ动态蝲入实现或者承这些接口或者基cȝ子类Q?lt;---------customized classloader
||
||
用customized classloader载入cLQ发现它有一个父cclassQextendsQ;
但是在蝲入它Ӟjvm先加载父cclassQ?q个父类是system classloader能识别的Q?Ҏ(gu)“委托机制”它将由system classloader来加载;
然后customized classloaderQ实际是system classloader来加载)再蝲入这个class,创徏一个实例,转型为父c;
jvm׃用system classloader再次载入父类classQ然后将此实例{型ؓ(f)q个父类classQ?/p>
q个q程加蝲了两个父cclassQ都是由system classloader载入Q即同一个classloader载入同一个文Ӟ造型不会(x)由异?/p>
web app server大概是这样工作的Q这栯入了Ml承了servlet的classq正运行它们,不管class是什么,都它们实例化Z个servlet class
题目如下Q?/p>
在考场的第一个做?/p>
当时发现旉够用Q进行了公式推理Q但未得律的真谛
每个都与T(3)可以直接发生关系Q关pL2的幂ơ方Q但最l没有得出公?br />遂改q如下:(x)
晚上w床上,怎么可能q样直接呢?
H然惛_最L(fng)的一点就是重复数的计,应该q行保存Q?br />如果正向逐个求然后保存,可行Q?br />如果倒向如何保存Q尚未想?br />大家来仁者见仁一下哦Q有更好的思\的请指点Q?br />public class T {
Map values = new HashMap();
public int t(int n){
int result = 0;
if (n == 0) {
result = 1;
} else if (n == 1) {
result = 1;
} else if (n == 2) {
result = 2;
} else {
result = 2 * t(n-1) - t(n-3);
}
return result;
}
}
目的Q都是ؓ(f)了解军_U程中的对同一变量的访问冲H?br>
ThreadLocal
. ?/span> ThreadLocal 保证不同U程拥有不同实例Q相同线E一定拥有相同的实例Q即为每一个用该变量的线E提供一个该变量值的副本Q每一个线E都可以独立改变自己的副本,而不是与其它U程的副本冲H?/span>
. ㈡优势:(x)提供了线E安全的׃n对象
. ㈢与其它同步机制的区别:(x)同步机制是ؓ(f)了同步多个线E对相同资源的ƈ发访问,是ؓ(f)了多个线E之间进行通信Q?/span> ThreadLocal 是隔d个线E的数据׃nQ从Ҏ(gu)上就不在多个U程之间׃n资源Q这样当然不需要多个线E进行同步了?/span>
. ㈣用技巧:(x)需要多个线E之间进行通信Q用同步机Ӟ如果需要隔d个线E之间的׃n冲突Q推荐?/span> ThreadLocal Q线E安全)
volatile
.?/span>volatile 修饰的成员变量在每次被线E访问时Q都从共享内存中重读该成员变量的倹{而且Q当成员变量发生变化ӞU程变化值回写到׃n内存?br>.㈡优势:(x)q样在Q何时刻,两个不同的线EL看到某个成员变量的同一个倹{?/span>
. ㈢缘由:(x)Java 语言规范中指出:(x)Z获得最佳速度Q允许线E保存共享成员变量的U有拯Q而且只当U程q入或者离开同步代码块时才与׃n成员变量的原始值对比?br> q样当多个线E同时与某个对象交互Ӟ必要注意到要让线E及(qing)时的得到׃n成员变量的变化?/span>
?/span> volatile 关键字就是提C?/span> VM Q对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互?/span>
. ㈣用技巧:(x)在两个或者更多的U程讉K的成员变量上使用 volatile 。当要访问的变量已在 synchronized 代码块中Q或者ؓ(f)帔RӞ不必使用?/span>
׃使用 volatile 屏蔽掉了 VM 中必要的代码优化Q所以在效率上比较低Q因此一定在必要时才使用此关键字?br>
阐释Q?br>U程Z提高效率Q将某成员变?/span>(?/span>A)拯了一份(?/span>BQ,U程中对A的访问其实访问的?/span>B?/span>
只在某些动作时才q行A?/span>B的同步,因此存在A?/span>B不一致的情况?/span>volatile是用来避免q种情况的?/span>
volatile告诉jvmQ?/span>它所修饰的变量不保留拯Q直接访问主内存中的Q也是上面说的A)
sleep() vs wait() sleep是线E类QThreadQ的Ҏ(gu)Q导致此U程暂停执行指定旉Q把执行Z(x)l其他线E,但是监控状态依然保持,到时后会(x)自动恢复?br> 调用sleep不会(x)释放对象锁?br>
wait是ObjectcȝҎ(gu)Q对此对象调用waitҎ(gu)D本线E放弃对象锁Q进入等待此对象的等待锁定池Q只有针Ҏ(gu)对象发出notifyҎ(gu)Q或notifyAllQ后本线E才
q入对象锁定池准备获得对象锁q入q行状态?br>
===================2007-05-01引用如下内容===========
protected Object initialValue() { return null; } |
public class ThreadLocal { private Map values = Collections.synchronizedMap(new HashMap()); public Object get() { Thread curThread = Thread.currentThread(); Object o = values.get(curThread); if (o == null && !values.containsKey(curThread)) { o = initialValue(); values.put(curThread, o); } return o; } public void set(Object newValue) { values.put(Thread.currentThread(), newValue); } public Object initialValue() { return null; } } |
public class SerialNum { // The next serial number to be assigned private static int nextSerialNum = 0; private static ThreadLocal serialNum = new ThreadLocal() { protected synchronized Object initialValue() { return new Integer(nextSerialNum++); } }; public static int get() { return ((Integer) (serialNum.get())).intValue(); } } |
int serial = SerialNum.get(); |
在上一?/strong>
送给Java初学?Q常被问到这个问题,ȝ一下)
”中主要描述了几个常见问题,本篇引用|上一作品来l阐qjava学习(fn)之\?/strong>
|
个h觉得Q初学者因为基薄弱Q从别h那里得到的徏议往往有两U情况:(x)
一是经怹c,l典书籍对于初学者往往q不适合Q?/span>
二可能是Ҏ(gu)感到好的Q但是处于的赯U不一P未必适合Q?/span>
我觉得初学者应该充分利用手头或者朋友或者从书店C本,感觉自己能接受的Q然后好好的M下,最好是多遍Q这样下来你q道什么适合自己了,q个时候听取的往往才可以奏效。毕竟有了这个缓冲过E,CQ这个缓冲过E绝Ҏ(gu)重要的?/span>
试想Q许多h把自ql验告诉你,是ؓ(f)了让你少走弯路;你经历过的会(x)觉得有道理;你没有经历的Q往往体会(x)不到Q经历了后才后?zhn)没有听从当初的徏议。初学者入门也是一L(fng)道理?/span>
回想当时入门javaӞ只有c的理论基Q把自己学校老师写的一?/span>java书在一q左右的旉内读?/span>7?/span>(2002q网l上java资料相对q是匮乏?/span>)Q书上标记的密密麻麻Q突焉qL(fng)灌顶豁然开朗了Q就入门了?/span>
2. 初学者应该用什么工P对于初学都来说是?/span>jdk比较好,q是?/span>eclips比较好呢Q?/span>
如果说工P推荐Eclipse?/span>NetBeanQ而不推荐JBuilder了?/span>
不伤?/span>JBuilder拥者,我从JB6用到2006Q也是一直捍?/span>JB的。但是现在的Eclipse发展的真的不错,而且是开元的Q所以推荐?/span>
NetBean5之前Q是非常鄙视的,C5后还Z错的Q与E可以有的一|也推荐?/span>
但对新手Q更推荐?/span>JDK+Editplus+JavaDoc的;在命令行下运行。ؓ(f)什么?所有的配置文g和代码推荐自己手写,q样对于初学者可以弄清楚原理。因?/span>IDE工具往往自动l你生成了,往往初学者得不到是其工作原理是怎么q行?
3. 初学者是不是应该x语言底层的东西?
x语言底层的东西,对于以后的深入学?fn)很重要的?/span>
当然基础也很重要?/span>
问题是不?x)走的时候,惌g太费心力了?/span>
q里需要辩证的看,Z吃饭Q就得符合或者适应时下业界的趋势;Z更好的发?/span>必须深入下去Q深入下L者ؓ(f)了以后的发展靠的是个人的努力。但是没有经验的累积以及(qing)大量代码的编写,x入下去近乎不可能?/span>
所以对初学者来_(d)唯一的就是脚t实圎ͼ写,写,写。篏U后pd解决问题的办法,形成解决问题的能力后Q就能在以后的学?fn)\途上更进一步?/span>
初学者可以不要盯着架构、模式之cȝQ但是在一定的代码量后Q都要反复的思考,是否可以抽取出来形成自己的一些公用的c,是否可以做成W合自己?fn)惯的开发包Q反复这个过E后Q在h先行者,或者在|络上查扄x面的讨论Q比?/span>JavaEyeQ,便会(x)得到一个质的升华?/span>
如果代码量篏计到4w行左叛_Q你再去看你看不懂的书,?x)发现很有心得或者豁然开朗了。当然如果这个过E缺乏了思考和ȝQ或许另当别论?/span>
?记得与一个很有功底的朋友在网上交时,他说的一句话,让我感触颇深:其实E序是不断试出来?...
送给初学者(二)Q?/strong>http://m.tkk7.com/crazycy/archive/2006/10/09/74030.html