2014年8月14日

财务制度题库

     摘要: 1财务制度题库 单选题 1.下列各会计要素,(   )不是反映财务状况的会计要素。 A.资产          B.负债          C.收入    ...  阅读全文

posted @ 2021-10-22 23:09 youngturk| 编辑 收藏

jquery 向mybitis后台传完整时间

var ssshsj = new Date( $("#ssshsj").val().replace(/-/g,"/")); 对于Ibatis操作Date/Time/DateTime,总结如下: 将pojo的属性类型设置为java.sql.Date(或java.sql.Time, java.sql.Timestamp),此时会严格遵循这三种类型的语义。但此方法因存在前文中提到的性能问题,在JDK1.6以前的JDK版本中能少使用就少使用。 如果你想在pojo中使用java.util.Date, 则要注意: 完整的日期时间,要确保jdbcType为空,或为DATE,TIME以外的值 只需要时间,要指定jdbcType=”TIME” 只需要日期,要指定jdbcType=”DATE”

posted @ 2017-03-26 00:22 youngturk| 编辑 收藏

webwork 实现数据生成text文件,并进行压缩,并进行下载

//实现压缩文件功能,采用commons-io-2.0.1.jar ,commons-compress-1.5.jar插件
        final OutputStream out = new FileOutputStream("D:/EDI/EDi.zip");  //实例文件输出流
        ArchiveOutputStream os = new ArchiveStreamFactory().createArchiveOutputStream(ArchiveStreamFactory.ZIP, out);  
        //实例化存档输出流,工厂方法创建zip的存档输出流
//        File f1 = new File(file.getPath());
        os.putArchiveEntry(new ZipArchiveEntry(file.getName()));  //生成存档文件名
        IOUtils.copy(new FileInputStream(file), os);  //添加拷贝存档文件
        
        os.closeArchiveEntry();  
        os.close();  
        
        //*************************
        try {
            File input = new File("D:/EDI/EDi.zip");//获得下载文件路径
            contentType="application/octet-stream";
            docStream = new FileInputStream(input);//获得输入流名称
            contentDisposition =URLEncoder.encode(input.getName() ,"UTF-8");
           } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
           }  
           return "download";
WEBWORK的文件下载机制。使用起来还是比较简单的。
下面是用法说明:
首先在一个ACTION中,如果判断有权限进行文件下载。
则:
1、读出该下载文件,并生成一个流。 文件名应当从请求的request中读出,或从用户的表中取出。
public String downLoadFile(String fileName){
   try {
    File input = new File("e:/engilish literature.doc");
    docStream = new FileInputStream(input);
    contentDisposition = "test.txt";
   } catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }  
   return "download";
}
2、将输出导向到一个特殊的RESULT中去。叫做Steam Result。
         <action name="register" class="com.job2easy.web.user.RegisterAction">
             <result name="success" type="dispatcher">
                 <param name="location">/home/register-result.jsp</param>
             </result>
             <result name="input">
                 <param name="location">/home/register.jsp</param>
             </result>
             <result name="download" type="stream">
                 <param name="contentType">application/x-msdownload</param>
                 <param name="inputName">docStream</param>
                 <param name="bufferSize">1024</param>              
                 <param name="contentDisposition">attachment;filename="${contentDisposition}"</param>
             </result>

             <interceptor-ref name="params"/>
         </action>
3、这中间有几个参数需要配置:
     contentType设成 application/x-msdownload 就可以。这样浏览器会保证弹出一个下载文件的对话框。
    inputName 这个比较重要,这个名字是输入流的名称, 以后要steam result的实现类中为根据OGNL的表达式去查找的。
    contentDisposition 这个是下载之后,保存在用户端的文件名称。${contentDisposition} 看一下代码。如果写成上述的方式,就有机会在ACTION中设置文件名。
4、另外一个参数:contentLength就是下载文件的大小,webwork的stream result似乎实现有问题,不能根据文件的大小动态进行设置,只能写死。
     这个参数的意义是告诉浏览下载的文件有多大,以便浏览器正确的显示进度条。如果这个功能很重要的话,可以重新写一个RESULT来实现。
0

posted @ 2016-08-09 17:49 youngturk 阅读(263) | 评论 (0)编辑 收藏

经典

http://blog.csdn.net/jackfrued/article/details/44921941

posted @ 2016-08-08 15:07 youngturk 阅读(180) | 评论 (0)编辑 收藏

sql行列互转

数据列出来如下:
 ID NAME    COUR SCORE
--- ------- ---- -----
  1 name_1  语文    33
  1 name_1  数学    63
  1 name_1  英语    71
  1 name_1  历史    68
  1 name_1  化学    94
  2 name_2  语文    85
  2 name_2  数学     4
  2 name_2  英语    98
  2 name_2  历史     9
  2 name_2  化学    12
  3 name_3  语文    49
  3 name_3  数学    96
  3 name_3  英语    30
  3 name_3  历史    60
  3 name_3  化学     2
要实现的行转列的效果如下(或者类似的结果):
 ID NAME    SCORES
--- ------- --------------------
  1 name_1  33,63,71,94,68
  2 name_2  85,4,98,12,9
  3 name_3  49,2,60,96,30
通过case表达式
select id,name,sum(case when course='语文' then score end) "语文",
sum(case when course='数学' then score end) "数学",
sum(case when course='英语' then score end) "英语",
sum(case when course='历史' then score end) "历史",
sum(case when course='化学' then score end) "化学"
from HANG2LIE
group by id,name;

union有去重功能:
结构如下:
 ID NAME       Chinese       Math    English    History  Chemistry
--- ------- ---------- ---------- ---------- ---------- ----------
  2 name_2          85          4         98          9         12
  1 name_1          33         63         71         68         94
  3 name_3          49         96         30         60          2
我们要实现如下的查询效果:列转行
 ID NAME     COUR SCORE
--- -------- ---- -----
  2 name_2   语文    85
  1 name_1   语文    33
  3 name_3   语文    49
  2 name_2   数学     4
  1 name_1   数学    63
  3 name_3   数学    96
  2 name_2   英语    98
  1 name_1   英语    71
  3 name_3   英语    30
  2 name_2   历史     9
  1 name_1   历史    68
  3 name_3   历史    60
  2 name_2   化学    12
  1 name_1   化学    94
  3 name_3   化学     2
1、集合查询
实现的SQL语句:
select id,name,'语文' course,chinese score from lie2hang
union
select id,name,'数学' course,math score from lie2hang
union
select id,name,'英语' course,english score from lie2hang
union
select id,name,'历史' course,history score from lie2hang
union
select id,name,'化学' course,chemistry score from lie2hang;

posted @ 2016-08-04 17:51 youngturk 阅读(190) | 评论 (0)编辑 收藏

oracle 分页 伪列 只能小于 不能大于

select * from (select A.*, rownum rn from T_CD_LOC A where rownum > 20) where rn <41 错


select * from (select t.* ,rownum rn from T_CD_LOC t where rownum<=40) where rn>=20 对
firstIndex=0
pageNumber
pageSize=20
select * from (select A.*,rownum rn from T_CD_LOC a where rownum < ((firstIndex+pageNumber+1)*pageSize) where rn >((firstIndex+pageNumber)*pageSize)

posted @ 2016-08-04 08:53 youngturk 阅读(210) | 评论 (0)编辑 收藏

js怎么刷新都不管用

js被缓存了,加控制版本 <script src="../lib_js/paymentplan.js?v=1"></script> 

posted @ 2016-07-13 15:36 youngturk 阅读(197) | 评论 (0)编辑 收藏

Ehcache学习 转2

     摘要: EhCache 分布式缓存/缓存集群开发环境:System:WindowsJavaEE Server:tomcat5.0.2.8、tomcat6JavaSDK: jdk6+IDE:eclipse、MyEclipse 6.6 开发依赖库:JDK6、 JavaEE5、ehcache-core-2.5.2.jarEmail:hoojo_@126.comBlog:http://blog.csdn...  阅读全文

posted @ 2016-07-10 17:14 youngturk 阅读(200) | 评论 (0)编辑 收藏

java 虚拟机监控

3、JConsole监控

     JMX(Java Management Extensions)是一个为应用程序植入管理功能的框架。JMX是一套标准的代理和服务,实际上,用户可以在任何Java应用程序中使用这些代理和服务实现管理。可以利用JDK的JConsole来访问Tomcat JMX接口实施监控,具体步骤如下:

1)首先,打开Tomcat5的bin目录中的catalina.bat文件,添加:

JAVA_OPTS="-Xms512m -Xmx512m -Xmn256m  -XX:PermSize=64m -XX:MaxPermSize=64m  -Djava.rmi.server.hostname=192.168.222.132 -Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"

-Dcom.sun.management.jmxremote:代表开启JMX的管理功能

2)重启tomcat,并查看监控端口(上面配置的1090)是否已启动

3)打开jdk的bin目录(如C:\Program Files\Java\jdk1.7.0_17\bin)下的JConsole,并输入iP和监控端口进行连接

     

 

监控结果:

     

posted @ 2016-07-09 16:06 youngturk 阅读(172) | 评论 (0)编辑 收藏

hibernate 删除关联表

http://www.itzhai.com/hibernate-one-to-many-association-mapping-configuration-and-the-cascade-delete-problem.html首先举一个简单的一对多双向关联的配置:

一的一端:QuestionType类

package com.exam.entity;
import java.util.Set;
public class QuestionType {
    private String typeName;
    private char typeUniqueness;
    private Set quesion;
    public String getTypeName() {
        return typeName;
    }
    public void setTypeName(String typeName) {
        this.typeName = typeName;
    }
    public char getTypeUniqueness() {
        return typeUniqueness;
    }
    public void setTypeUniqueness(char typeUniqueness) {
        this.typeUniqueness = typeUniqueness;
    }
    public Set getQuesion() {
        return quesion;
    }
    public void setQuesion(Set quesion) {
        this.quesion = quesion;
    }
}

配置文件:

<hibernate-mapping package="com.exam.entity">
    <class name="QuestionType" table="exam_question_type">
        <id name="typeName" column="type_name"></id>
        <property name="typeUniqueness"  column="type_uniqueness"/>
        <set name="quesion" inverse="true" cascade="delete">
            <key column="question_type_name"/>
            <one-to-many class="Question"/>
        </set>
    </class>
</hibernate-mapping>

多的一端:Question类

package com.exam.entity;
import java.util.Date;
public class Question {
    private int questionNo;
    private QuestionType questionType;
    private String questionsTitle;
    public int getQuestionNo() {
        return questionNo;
    }
    public void setQuestionNo(int questionNo) {
        this.questionNo = questionNo;
    }
    public QuestionType getQuestionType() {
        return questionType;
    }
    public void setQuestionType(QuestionType questionType) {
        this.questionType = questionType;
    }
    public String getQuestionsTitle() {
        return questionsTitle;
    }
    public void setQuestionsTitle(String questionsTitle) {
        this.questionsTitle = questionsTitle;
    }
}

配置文件:

<hibernate-mapping package="com.exam.entity">
    <class name="Question" table="exam_question">
        <id name="questionNo" column="question_no" >
            <generator class="increment" />
        </id>
        <many-to-one name="questionType" column="question_type_name"/>
        <property name="questionsTitle" column="questions_title" length="200" />    
    </class>
</hibernate-mapping>

首先说明一下一些常用的属性:

<many-to-one>元素包含以下属性:

name:设定映射的持久化类的属性名
column:设定和持久化类的属性对应的表的外键
class:设定持久化类的属性的类型
cascade:设定是否级联
lazy:设定是否延迟加载

<set>元素包含以下属性:

name:设定映射的持久化类的属性名
cascade:设置是否级联
inverse:设定反向控制,如果为true则一的一端不维护外键
<key>:设定与所关联的持久化类对应的表的外键。
one-to-many:设定所关联的持久化类

如果要对一对多关联映射进行级联删除,可以按照上面的举例进行配置:

首先看到一的一端:

<set name="quesion" inverse="true" cascade="delete">
    <key column="question_type_name"/>
    <one-to-many class="Question"/>
</set>

这里设置inverse表示一的一端不维护外键,设置cascade=”delete”表示删除一的一端时对关联到得多的所有的对象也一起删除

再看到多的一端:

<many-to-one name="questionType" column="question_type_name"/>

这里的column表示外键的名,需要和一的一端设置的key标签里的column保持一致,表示维护同一个键值。

可以按照如下的代码执行删除操作:

session.beginTransaction();

QuestionType questionType = (QuestionType) session.load(QuestionType.class, "判断题");            
session.delete(questionType);        
session.getTransaction().commit();

这里使用load查上来的对象是持久状态的(Persistent),只有是Persistent状态的对象才可以使用session.delete()操作进行级联删除,由new创建的对象属于Transient状态,不能进行session.delete()操作。

posted @ 2016-07-09 14:21 youngturk 阅读(294) | 评论 (0)编辑 收藏

hibernate 删除关联表

需要先删子表,再删除主表,否则报错 好文章 http://www.itzhai.com/hibernate-one-to-many-association-mapping-configuration-and-the-cascade-delete-problem.html

posted @ 2016-07-09 14:18 youngturk 阅读(200) | 评论 (0)编辑 收藏

middlegen生成pojo

http://blog.csdn.net/itcareerist/article/details/5896143

posted @ 2016-07-05 14:24 youngturk 阅读(185) | 评论 (0)编辑 收藏

MyBatis 需要研究

http://www.cnblogs.com/xdp-gacl/p/4261895.html

posted @ 2016-06-27 13:47 youngturk 阅读(134) | 评论 (0)编辑 收藏

ftp socket

http://www.ibm.com/developerworks/cn/linux/l-cn-socketftp/

posted @ 2016-06-27 12:45 youngturk 阅读(119) | 评论 (0)编辑 收藏

XML面试题

http://blog.csdn.net/sweetsnow24/article/details/7447110 http://jingyan.baidu.com/article/b7001fe1738d9a0e7282dda6.html http://wenku.baidu.com/link?url=YjPcc8q-E9jnAEqsEJQZ7juMw8TICa0q9ppU3ICqEyQJBl4JGQynegQT03DQA0oyA-CxGAtDKJ_pvuvo3prfVeLEsxzC7VUWjWMsQVAxht_ 问题1:XML是什么?   答:XML即可扩展标记语言(Extensible Markup language),你可以根据自己的需要扩展XML。XML中可以轻松定义, 等自定义标签,而在HTML等其他标记语言中必须使用预定义的标签,比如

,而不能使用用户定义的标签。使用DTD和XML Schema标准化XML结构。XML主要用于从一个系统到另一系统的数据传输,比如企业级应用的客户端与服务端。   问题2:DTD与XML Schema有什么区别?   答:DTD与XML Schema有以下区别:DTD不使用XML编写而XML Schema本身就是xml文件,这意味着XML解析器等已有的XML工具可以用来处理XML Schema。而且XML Schema 是设计于DTD之后的,它提供了更多的类型来映射xml文件不同的数据类型。DTD即文档类型描述(Document Type definition)是定义XML文件结构的传统方式。   问题3:XPath是什么?   答:XPath是用于从XML文档检索元素的XML技术。XML文档是结构化的,因此XPath可以从XML文件定位和检索元素、属性或值。从数据检索方面来说,XPath与SQL很相似,但是它有自己的语法和规则。   问题4:XSLT是什么?   答:XSLT也是常用的XML技术,用于将一个XML文件转换为另一种XML,HTML或者其他的格式。XSLT为转换XML文件详细定义了自己的语法,函数和操作符。通常由XSLT引擎完成转换,XSLT引擎读取XSLT语法编写的XML样式表或者XSL文件的指令。XSLT大量使用递归来执行转换。一个常见XSLT使用就是将XML文件中的数据作为HTML页面显示。XSLT也可以很方便地把一种XML文件转换为另一种XML文档。   问题5:什么是XML元素和属性   答:最好举个例子来解释。下面是简单的XML片断。   Xml代码         6758.T   2300         例子中id是元素的一个属性,其他元素都没有属性。   问题6:什么是格式良好的XML   答:这个问题经常在电话面试中出现。一个格式良好的XML意味着该XML文档语法上是正确的,比如它有一个根元素,所有的开放标签合适地闭合,属性值必须加引号等等。如果一个XML不是格式良好的,那么它可能不能被各种XML解析器正确地处理和解析。   问题7:XML命名空间是什么?它为什么很重要?   答:XML命名空间与Java的package类似,用来避免不同来源名称相同的标签发生冲突。XML命名空间在XML文档顶部使用xmlns属性定义,语法为xmlns:prefix=’URI’。prefix与XML文档中实际标签一起使用。下面例子为XML命名空间的使用。   Xml代码      837363223         问题8:DOM和SAX解析器有什么区别   答:这又是一道常见面试题,不仅出现在XML面试题中,在Java面试中也会问到。DOM和SAX解析器的主要区别在于它们解析XML文档的方式。使用DOM解析时,XML文档以树形结构的形式加载到内存中,而SAX是事件驱动的解析器。   问题9:XML CDATA是什么   答:这道题很简单也很重要,但很多编程人员对它的了解并不深。CDATA是指字符数据,它有特殊的指令被XML解析器解析。XML解析器解析XML文档中所有的文本,比如This is name of person,标签的值也会被解析,因为标签值也可能包含XML标签,比如First Name。CDATA部分不会被XML解析器解析。   问题10:Java的XML数据绑定是什么   答:Java的XML绑定指从XML文件中创建类和对象,使用Java编程语言修改XML文档。XML绑定的Java API,JAXB提供了绑定XML文档和Java对象的便利方式。另一个可选的XML绑定方法是使用开源库,比如XML Beans。Java中XML绑定的一个最大的优势就是利用Java编程能力创建和修改XML文档。   以上的XML面试问答题收集自很多编程人员,但它们对于使用XML技术的每个人都是有用的。由于XML具有平台独立的特性,XPath,XSLT,XQuery等XML技术越来越重要。尽管XML有冗余和文档体积大等缺点,但它在web服务以及带宽、速率作为次要考虑因素的系统间数据传输起很大作用,被广泛用于跨平台数据传输。

posted @ 2016-06-24 16:41 youngturk 阅读(164) | 评论 (0)编辑 收藏

SQL SERVER 的用户数,连接,连接池 license

http://www.cnblogs.com/qanholas/p/3904833.html SQL SERVER 理论上有32767个逻辑连接,SQL SERVER根据系统自行调配连接池。 首先 ,操作系统的用户数:即同时通过网络连接到这台电脑上面的用户限制,以5用户操作系统,搭建的文件服务器为例,去同时访问这个文件服务器的网络用户为5个。 下面说说SQL server,购买数据库有两种方式,1、根据用户数购买。2、根据cpu个数购买。 根据用户数购买,假如你购买了一个50用户的数据库,那么可以通过网络访问数据库的人数限制为50。 根据cpu个数购买的数据库访问人数不受限制,服务器上面有几颗cpu就要买几个授权的SQL server,但是如果你只买一个授权的话数据库也可以正常运行,但是微软认为你的数据库不合法。就如同盗版系统。 一个连接不等于一个用户,单独一个用户可以有超过一个的连接,单独一个连接可以有超过一个用户。 你可以运行里面输入perfmon,然后加入下面两个计数器进行对比 SQLServer: General Statistics — Logical Connections:与系统建立的逻辑连接数。SQLServer: General Statistics — User Connections:连接到系统的用户数。 打个比喻 sql server是你家的房子 用户数 是你家房子钥匙 连接数 是你家房子能进去的人 不是很恰当,但是基本能说明问题 一个房子有多少个钥匙是明确的,但是每个钥匙是可以让多个人进去 也就是说,sql server的用户是可以登陆sql server进行操作的,而连接数指的是使用某个用户名登陆的为了执行某个具体操作的一个连接。 通常一个SQL SERVER 查询器,一个ADOCONNECTION是一个连接。 在SQL Server里查看当前连接的在线用户数 use master select loginame,count(0) from sysprocesses group by loginame order by count(0) desc select nt_username,count(0) from sysprocesses group by nt_username order by count(0) desc 如果某个SQL Server用户名test连接比较多,查看它来自的主机名: select hostname,count(0) from sysprocesses where loginame='test' group by hostname order by count(0) desc 如果某个SQL Server用户名test连接比较多,查看它最后一次操作的时间范围分组: select convert(varchar,last_batch,111),count(0) from sysprocesses where loginame='test' group by convert(varchar,last_batch,111) order by count(0) desc 如果从主机(www)来的连接比较多,可以查看它的进程详细情况 select * from??sysprocesses where hostname='www' 如果www机器主要提供网页服务,可能是asp程序处理连接时出了问题, 生成杀这些进程的SQL语句: select 'kill '+convert(varchar,spid) from sysprocesses where hostname='www' 如果这样的问题频繁出现,可以写一个存储过程sp_KillIdleSpids.sql, 写一个作业, 执行它, 来自动杀掉从主机(www)来但已经一天没有响应的用户连接. ? ? ? -------------------------------- SQL Server的用户及权限? ?sysadmin 可以在 SQL Server 中执行任何活动? serveradmin 可以设置服务器范围的配置选项 关闭服务器? setupadmin 可以管理链接服务器和启动过程? securityadmin 可以管理登录和 CREATE DATABASE 权限 还可以读取错误日志和更改密码? processadmin 可以管理在 SQL Server 中运行的进程? dbcreator 可以创建 更改和除去数据库? diskadmin 可以管理磁盘文件? bulkadmin 可以执行 BULK INSERT 语句? ...... 最大连接数是指数据库能承受的最大并发访问数量 SQL Server的并发用户数或者license怎么理解? 华软论坛 2005-12-06 13:38:55 在 MS-SQL Server / 基础类 提问 盗版的有并发用户数的限制吗?正版好像有10用户,50用户的版本,如果用C/S架构的话,每个客户端连接算不算一个用户? 后来有段时间好像改到 只按CPU购买License了。现在又好像见到购买连接数的license. 讲了这么一堆,想告诉你的是,如果你只有10用户的License,其实也是没有限制的。这是微软的市场人员亲口告诉我的。 [华 软 网] 欢迎转载,但请保留出处,本文章转自[华软网] 原文链接:http://www.huarw.com/db/dbbbs/MSSQLServer/200512/735120.html 你指的是购买许可吧? SQL 提供3种购买方式 1) Processor license. (按CPU购买) 要求为运行SQL Server 2000的操作系统上的每个CPU购买许可. 这种方式不需要购买客户端访问许可. 2) Server plus device CALs. (服务器许可加每设备客户端访问许可) 运行SQL Server 2000的服务器需要一个许可, 每个访问SQL Server 2000的设备需要一个客户端访问许可. 3) Server plus user CALs. (服务器许可加每用户客户端访问许可) 运行SQL Server 2000的服务器需要一个许可, 每个访问SQL Server 2000的用户需要一个客户端访问许可 2、每客户 每客户授权模式要求每个将访问 SQL Server 2000 服务器的设备都具有一个客户端访问许可证。对于客户端连接到不止一个服务器的网络,每客户模式通常更划算。 在编辑框中,选择要授权的设备数。 选择授权模式: 使用该对话框设置授权模式,以使客户端可以访问 Microsoft? SQL Server? 的该实例。SQL Server 2000 支持两种客户端访问授权模式,一个用于设备,另一个用于处理器。 设备可以是工作站、终端或运行连接到 SQL Server 实例的 SQL Server 应用程序的任何其它设备。 处理器指的是安装在运行 SQL Server 2000 实例的计算机上的中央处理器 (CPU)。一个计算机上可以安装多个处理器,从而需要多个处理器许可证。 一旦设置了授权模式便无法再更改。可以在安装 SQL Server 之后添加设备或处理器许可证,这使用 "控制面板 "中的 SQL Server 2000 授权安装实用工具来进行。 1、授权模式 当从 "控制面板 "访问该对话框时,安装过程中选择的模式在默认情况下为选中,同时显示以前选择的设备数或处理器数。 2、每客户 每客户授权模式要求每个将访问 SQL Server 2000 服务器的设备都具有一个客户端访问许可证。对于客户端连接到不止一个服务器的网络,每客户模式通常更划算。 在编辑框中,选择要授权的设备数。 3、处理器许可证 使用处理器许可,安装在运行 SQL Server 的计算机上的每个处理器都需要一个许可证。处理器许可证允许任意数目的设备访问服务器,无论它们是通过 Intranet 还是 Internet。 使用处理器许可,SQL Server 2000 可以利用每个安装的处理器,并支持不限数目的客户端设备。通过 Internet 提供对 SQL Server 数据库的访问的客户或拥有大量用户的客户通常选择处理器许可证。 在编辑框中选择要授权的处理器数。 SQL Server安装成功后,重起计算机后SQL Server自动启动服务。 10用户不是指的连接用户 在创建自定义控制台时,可以给控制台指派两种常用访问选项中的一种:作者模式或用户模式。依次有三个级别的用户模式,因此共有四种默认访问控制台的选项: 作者模式 用户模式-完全访问 用户模式-受限访问,多窗口 用户模式-受限访问,单窗口 你安装的是企业版,10个客户端是指你能够在别的机子上只能安装10个Sql客户端同它连接

posted @ 2016-06-24 15:00 youngturk 阅读(495) | 评论 (0)编辑 收藏

三分钟让你看懂java网络通信

http://i-lolo.iteye.com/blog/1611562 在进入网络通信之前,让我们来普及一点网络基础概念。如果你是有一定的计算机网络基础,请直接跳到第五点之后开始阅读。 第一、 什么是计算机网络? 书本上那些文绉绉的概念我们可以不去理,我告诉你,我们两台电脑连在一起就组成了一个计算机网络。其实我们的电脑甚至是全世界的电脑都是连着的,只要你的电脑连着网,你就在这个巨大的计算机网络里,你也许会问为什么我和他们是连着的啊?大家知道自己是怎么上的网?ADSL是吧,拨号上网。换个比方说吧,我们在公司我们的电脑通过网线,双绞线,然后是Hub(集线器),连接到胡哥的电脑,然后胡哥的机子通过拨号,ADSL,连到电信的网关那儿,然后中国电信通过海底光缆和美国电信网关连接,然后再像刚刚我们连接中国电信一样,逆推过去,连接到美国每一台联网的计算机。所以说只要你连着网,你就是和全世界的在线用户连着。这是一个巨大的计算机网络。非常巨大。 第二、 计算机网络的主要功能? 资源共享、信息传输与集中处理、均衡负荷与分布处理、综合信息服务(www/综合数字网络 ISDN)。这些个功能,不多说。这些你不平时都在用么?你的资源能够上传共享给其他人,有的人平时还很喜欢聊QQ,是吧,所以上面说的这四个也许还有更多的什么功能都是些冠冕堂皇的话,稍微看下就好。用了自然就晓得了。 第三、 什么是网络通信协议? 我来问你,为什么你说话身边的人能够听的懂,别人说的话你为什么也能够听懂,而为什么如果你去对一个外国人说话或者一个外国人来和你说话你们却互相听不懂呢?你会说废话嘛因为我说的是中文,是汉语,中国人说的都是汉语,而外国人说的是另一种语言,是外语。就是这样,网络通信协议就像我们的中文一样,她就是我们之间的共同语言,他规定了我们之间怎么说话,我先说什么你再说什么,你怎么说,而我应该怎么听。而网络通信得先规定约定一些俗成的网络通信协议,先说好,两台计算机之间什么收发信息,信息格式是什么,信息怎么发,怎么接收,而万一出错怎么办怎么处理。没有了这个协议,两台电脑就不知道互相之间怎么说话,就像你对一头大母猪说完爱你,而人家根本就不知道你在说什么。 在这儿和大家提一下网络协议的分层思想。学过计算机网络的同学都知道有两种基本的国际标准分层模型,一个是OSI参考模型,一个是TCP/IP参考模型。OSI参考模型,是国际标准化组织搞出来的开放互联传统模型,一共有七层:物理/数据链路/网络/传输/会话/表示/应用。学网络和硬件的一般都要熟悉这七层标准,至于这七层都是干嘛的,大家自己问度娘或者自己看关于网络的书去。(中南大学高阳教授主编了一本叫《计算机网络原理与实用技术》的书,里边很详尽的介绍了这个OSI参考模型,没记错的话应该是在第一章1.4.5里,是放在TCP/IP协议之后的……)这里就不多说了,因为对于咱们编程的软件人员来说,实际当中的应用,是分为四层,也就是TCP/IP参考模型。最底层物理+数据链路层/网络层/传输层/应用层。我们编的程序是位于应用层,所以说,我们一直是在和哪一层打交道?TCP/IP层。我们编写一个程序发送一些数据,发给传输层,TCP/IP层,在这一层对数据进行封装,按照先前约定的协议,然后走向下一层,通过网线,再走到物理数据链路层,这时候数据就变成了一连串的01010101,到达对面之后逆推上面的过程,进行解封,ok,信息发送完毕。这儿涉及到比较多的网络底层,目前我们不需要过多了解,因为我们要做的工作不需要了解牵扯到到这么底层的东西,如果你想深入了解或者今后你想做杀毒软件什么的,去读《TCP/IP详解》。 第四、 IP——(Internet Protocol网络之间互连的协议)? 你不用管其他的,你只需要知道IP这个东西给我们做出的最大贡献,就是给我们每一台电脑提供了一个独一无二的IP地址。你想我的机器要和你的机器交流说话,我得知道你的机器叫什么,你的机器得有一个独一无二的区别标识,否则的话我就不知道传的信息有没有传到你那儿,也不知道这信息到底传给谁。IP地址这东西我们都知道吧?像我的本机IP: 113.240.187.242 这是湖南省长沙市的IP。他是由四个字节组成的(也就是说每一个值不能超过255)。(这个是IPV4,能够组成将近四亿多地址,现在已经出来了IPV6,高档货,八个字节,地址数是IPV4的几何倍数)IPV4的IP地址按照其网络IP段和主机IP段占的字节数分ABC三类网。这个这里不说,大家自己去了解,好吧?拿高阳教授的那本书翻翻。顺带看看子网掩码啊网关啊什么的。自己去了解。在这儿我就累得给你敲了。 第五、 TCP协议和UDP协议? 好了,上一步里我们通过独一无二的IP地址找到了对方连在了一起。我们可以通话了,关于通话我们有两种方式: 第一、 TCP协议,什么叫TCP协议?Transmission Control Protocol 传输控制协议TCP是一种面向连接(连接导向)的、可靠的、基于字节流的运输层(Transport layer)通信协议。什么叫可靠的?打个比方,我们打电话,上一步通过IP找到对方就相当于拨号打通了你的电话,你拿起电话接了,我说一句“喂?”,如果你这边不回应,我就会杵这儿一直“喂”下去,是不?因为不知道你那边到底接到了听到了我的话没有,所以你这边一定要告诉我你听到了你收到了我刚刚的那句信息,我才会接着给你说下面的话给你发下面的数据。我每发一次信息我要你给我确认收到了,然后我再给你发接下来的东西,这个就叫可靠。在TCP/IP协议里边这叫“三次握手”机制。怎么握手,握手是怎么回事,问度娘,好吧? 第二、 UDP协议。User Datagram Protocol的简称, 中文名是用户数据报协议,是 OSI 参考模型中一种无连接的传输层协议。UDP这种方式相对于TCP来说更加简单。UDP说话就是,我给你说一句话,你听没听到我不管。就像发电报,“黄河黄河我是长江!”哐当一下就发出去了。不管黄河收到没有。两种方式一种安全可靠但是慢,一种简单快捷但是不可靠。根据不同的需求选择。像我们平时聊QQ开视频啊什么的,用的就是UDP,因为我们传输的这些个数据丢个一两个包什么的无所谓,顶多就是视频多了几个马赛克,是吧。那么平时我们玩的网络游戏,像CF啊魔兽世界啊,是哪一种呢?自己想,好吧? 第三、 中南-马志丹 http://java-mzd.javaeye.com 惊喜看得到! 基础普及完了,接下来我们来看看为什么要去做网络通信。这一段我就简单点说。在计算机刚出来那会儿 ,那时候的人们都觉得计算机这东西就是主要为计算而存在的就是一个计算工具,但是自从1983年起,TCP\IP协议的出现,让计算机从此转变为了人们的一个交流工具。自那以后,只要你有一台电脑,不管你是开网页看电影,还是上人人找朋友,不管你是登邮箱收发邮件,还是登QQ聊天,你的生活的方方面面都离不开那电脑屏幕后边的网络技术。换句话说,如果没有了网络通信技术,电脑以及大多数软件将会失去他们原有的生命力。就像一棵大树没有根。没有网络通信就没有如今繁荣的QQ世界,没有了网络通信,世界上那些个IT巨头诸如IBM诸如谷歌,将会如断线风筝落日残阳。我想说,如果你不懂网络通信技术,你就不是一个合格的程序员,如果你不精通网络通信技术,你就无法开发出一款真正优秀的营运软件!除非你想永远停留在枯燥的单机时代,你想让自己的技术永远留在表层。 现在,让我们来考虑如何实现。 在做实现之前,我想先让大家明白几个概念: 1) Socket A. 两个Java应用程序可通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称为一个Socket B. Socket通常用来实现client-server连接 C. Java.net包中定义的两个类Socket和ServerSocket,分别用来实现双向连接的client和server端 D. 建立连接时所需要的寻址信息为远程计算机的IP地址和端口号(Port number) 上面我们提到了IP地址,那是每一台电脑独一无二的一个地址标识,是为了对方计算机能够找得到你给你发信息。建立连接我们很显然需要这个信息才能够完成。那么这个端口号又是用来干什么的呢?举个例子,假如说我电脑上现在上着人人和QQ,你的电脑上也是上着人人和QQ,如果我用QQ给你发一条消息他怎么知道就发到你的QQ上而不会在你的人人上呢?是吧?所以说光用IP地址是无法区分到不同的应用程序的。所以需要端口号来达到这个作用。端口号在计算机内部是用两个字节来表示,也就是说总共有65536个端口。在这儿需要注意下面两个点: •1.1024之前的端口我们自己编的程序不要征用它,因为这些端口是给系统用的。比如说80端口,胡哥给咱们讲过的。干嘛的?负责处理HTTP上网访问网页等等的端口。还有就是21端口,FTP的,是吧?还有其他的一些著名端口,想知道问度娘去,好吧?在这里就不罗嗦了。 •2.TCP端口和UDP端口是分开的,比如说TCP有个8888端口,他和你的UDP8888端口是不一样的。 •3.上述每一类有65536个端口。也就是说我们的计算机能够运行131072个程序,只要你电脑吃得消。 既然要实现通信,那我们肯定要确定两个通信对象,一个是服务器对象server,一个是客户端对象client。我们需要知道,这两个对象是两个应用程序,他们的对话,是两个不同的程序之间的对话。你会说我只有两个对象也还没法实现他们之间的交互啊,不用急,我也知道他们两个不是神仙会心有灵犀。两个对象之间想要实现互相之间的信息交互,就必须要有一个通道。这个通道就像是一根管子,一头扎在服务器端,一头插在客户端。信息就在这根管子里来来往往。这根管子怎么插呢,插在哪儿呢?这个时候就需要用到刚刚提到的Socket了。 Socket的意思呢就是一个插座,服务器和客户端各有一个插座,安插在各自的一个端口上,管子插在这两个插座上,然后在他们这两个端口上接入数据流。Socket通常用来实现server-client连接。Java里面有一个包java.net,他下边有定义了两个类,Socket和ServerSocket,分别用来实现双向连接的server端和client端。 接下来我们来建立TCP服务器端和客户端。 服务器端:我们用的是ServerSocket,新建一个server插座,并且交给他一个端口号,这个插座他有一个非常方便的构造方法ServerSocket(int port),让他知道自己监听哪一个端口,然后新建一个socket对象,开机,并用.accept语句让他处在待机状态,等待接受client的接入。一旦有客户端接入就将它赋给新建的Socket对象,并且用.getInputStream以及.getOutputStream命令获得他的输入输出流。这个流,就是一根管子,信息都在这根管子里流通。这样说东西不怎么好说,那么我们就在这个流上面再包一层,将这个流封装成DataOutputStream(),DataInputStream。然后就可以利用输出流(这个是相对于服务器来说,这个输出流到了客户端就成了输入流了)来.write信息,利用输入流来.read()获取客户端发来的信息。Ok,接收完了,.close关闭输入输出流,以及关闭socket,关机。 客户端:写法和服务器端有点类似,新建一个插座,这儿需要留意的是,客户端需要用到的插座是Socket而不是ServerSocket,新建一个Socket牌插座,同样用他的Socket(String host,int port)构造方法方法给他一个IP地址和端口号,让它拨打区号以及具体电话号,这个和服务器端的IP地址以及端口号要一致,ok,这个时候server就相当于申请连接到服务器的某一个端口上了。两个程序就等于是连接上了。但是有些人就会问了啊,这只是客户端申请连接,人家服务器接不接受呢。好,前面我们的服务器不是提到了.accept么,这个方法就是用来接受客户端的,这个时候就是:你申请连接,我接受连接,接下来,照着上面服务器一样,客户端也获取到自己的输入输出流,封装,用输出流写出信息。咱们之间就可以互相通信了。还有一个问题啊,要是如果有另一个客户端接入了呢?简单,那就再.accept一下。如果有N多客户端接入,那就不断的.accept,不断循环它。这个问题大家都知道可以用while语句。 具体的敲法,请看我给大家附上的代码实现。下面给大家看下Socket通信模型。看着这个模型,再回头看看上面给大家唠叨的那些个点,我想大家都知道服务器和客户端该怎么去写怎么去实现通信了吧? 好了,这一段“三分钟让你看懂”到此就结束了,想来大家对网络通信也该有了一个相对清晰的认识。如果你还想了解学习更多的网络通信方面的知识,如果你还想知道如何去实现一些更多的通信功能,比如建立公共聊天室实现群聊,又比如建立一个以互联网为基础的以网络画板为主体的协助平台,又比如,你想做一个自己的软件来实现像QQ一样MSN一样或者像人人桌面一样的各种功能……请继续关注我们的随后更新。请记住,我们是ZCL,我们是一群简单快乐的牧码人! 后记:第一篇正儿八经的技术日志,4K多全手打,这样说起来应该蛮自豪的感觉。但是说实话还是觉得自己写的有些乱。自己只是把课堂上老师们讲的一些知识点,根据自己敲的代码以及做了的一些课堂笔记,罗列了出来。也查了一些在线资料和书籍,像度娘,像学校发的那本我都没怎么动过的《计算机网络原理和实用技术》。在前面花了好些篇幅来讲计算机网络基础知识,是因为我给自己定下的目标就是让任何一个人甚至你是没怎么学过接触过java或者计算机网络这一块,看了我的博客之后,都能够对网络通信有一个比较清晰的认识,而让接触过java的人知道怎么样初步的去实现两个软件或者说程序之间的通信,知道他们之间是怎么回事儿并且自己动手实现它。这确实是一个有点难度的过程。但是你如果把这个都搞定了,那么,你的java网络通信就基本可以说入了一个门了。我似乎听见了胡哥用他那一惯的口吻在我身后说,这种程度,要说入门还早的很呢!当然咯,就算我现在做到网络画图板做到网络文件传输,也感觉自己只是进了一个门,门后的世界无比之大,等待我们不断的去探索,去创新,去创造它。生命有限,学海无涯;人有老时,学无止境嘛。发现的问题蛮多。但获得的收获也不少。果然检验自己是否学会掌握一个东西的最好办法就是尝试着去教给别人。只有你能够很清晰的把事儿给别人说清楚了教会了,你才能说自己懂了。写完这篇博客,感觉自己对网络通信的理解又加深了一些,对其中的一些知识点的掌握也更加牢靠了一些。只言片语薄闻浅见,希望大家多多批评不吝赐教! 最后的最后:用胡哥的一句话来与君共勉吧! 标准即平庸,合格即废物。 (附)服务器端代码: Java代码 收藏代码 package con120722; import java.net.*; import java.io.*; public class Server { private ServerSocket ss; private Socket socket; private BufferedReader in; private PrintWriter out; public Server() { try { ss = new ServerSocket(10000); while (true) { socket = ss.accept(); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(),true); String line = in.readLine(); out.println("you input is :" + line); out.close(); in.close(); socket.close(); } } catch (IOException e) {} } public static void main(String[] args) { new Server(); } } 客户端代码: Java代码 收藏代码 package con120722; Java代码 收藏代码 import java.io.*; import java.net.*; public class Client { Socket socket; BufferedReader in; PrintWriter out; public Client() { try { socket = new Socket("localhost", 10000); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(),true); BufferedReader line = new BufferedReader(new InputStreamReader(System.in)); out.println(line.readLine()); line.close(); out.close(); in.close(); socket.close(); } catch (IOException e) {} } public static void main(String[] args) { new Client(); } }

posted @ 2016-06-23 10:02 youngturk 阅读(236) | 评论 (0)编辑 收藏

Xms Xmx PermSize MaxPermSize 区别 java 内存

http://www.cnblogs.com/mingforyou/archive/2012/03/03/2378143.html http://www.educity.cn/wenda/450855.html Eclipse崩溃,错误提示: MyEclipse has detected that less than 5% of the 64MB of Perm Gen (Non-heap memory) space remains. It is strongly recommended that you exit and restart MyEclipse with new virtual machine memory paramters to increase this memory. Failure to do so can result in data loss. The recommended Eclipse memory parameters are: eclipse.exe -vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M 1.参数的含义 -vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M -vmargs 说明后面是VM的参数,所以后面的其实都是JVM的参数了 -Xms128m JVM初始分配的堆内存 -Xmx512m JVM最大允许分配的堆内存,按需分配 -XX:PermSize=64M JVM初始分配的非堆内存 -XX:MaxPermSize=128M JVM最大允许分配的非堆内存,按需分配 我们首先了解一下JVM内存管理的机制,然后再解释每个参数代表的含义。 1)堆(Heap)和非堆(Non-heap)内存 按照官方的说法:“Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。”“在JVM中堆之外的内存称为非堆内存(Non-heap memory)”。 可以看出JVM主要管理两种类型的内存:堆和非堆。简单来说堆就是Java代码可及的内存,是留给开发人员使用的;非堆就是JVM留给自己用的, 所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。 堆内存分配 JVM初始分配的堆内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的堆内存由-Xmx指定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制; 空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。因此服务器一般设置-Xms、-Xmx 相等以避免在每次GC 后调整堆的大小。 说明:如果-Xmx 不指定或者指定偏小,应用可能会导致java.lang.OutOfMemory错误,此错误来自JVM,不是Throwable的,无法用try...catch捕捉。 非堆内存分配 JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。(还有一说:MaxPermSize缺省值和-server -client选项相关, -server选项下默认MaxPermSize为64m,-client选项下默认MaxPermSize为32m。这个我没有实验。) 上面错误信息中的PermGen space的全称是Permanent Generation space,是指内存的永久保存区域。还没有弄明白PermGen space是属于非堆内存,还是就是非堆内存,但至少是属于了。 XX:MaxPermSize设置过小会导致java.lang.OutOfMemoryError: PermGen space 就是内存益出。 说说为什么会内存益出: (1)这一部分内存用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和存放Instance的Heap区域不同。 (2)GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS 的话,就很可能出现PermGen space错误。 这种错误常见在web服务器对JSP进行pre compile的时候。 2)JVM内存限制(最大值) 首先JVM内存限制于实际的最大物理内存,假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制, 这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制了。 2. 为什么有的机器我将-Xmx和-XX:MaxPermSize都设置为512M之后Eclipse可以启动,而有些机器无法启动? 通过上面对JVM内存管理的介绍我们已经了解到JVM内存包含两种:堆内存和非堆内存,另外JVM最大内存首先取决于实际的物理内存和操作系统。所以说设置VM参数导致程序无法启动主要有以下几种原因: 1) 参数中-Xms的值大于-Xmx,或者-XX:PermSize的值大于-XX:MaxPermSize; 2) -Xmx的值和-XX:MaxPermSize的总和超过了JVM内存的最大限制,比如当前操作系统最大内存限制,或者实际的物理内存等等。说到实际物理内存这里需要说明一点的是, 如果你的内存是1024MB,但实际系统中用到的并不可能是1024MB,因为有一部分被硬件占用了。 3. 为何将上面的参数写入到eclipse.ini文件Eclipse没有执行对应的设置? 那为什么同样的参数在快捷方式或者命令行中有效而在eclipse.ini文件中是无效的呢?这是因为我们没有遵守eclipse.ini文件的设置规则: 参数形如“项 值”这种形式,中间有空格的需要换行书写,如果值中有空格的需要用双引号包括起来。比如我们使用-vm C:/Java/jre1.6.0/bin/javaw.exe参数设置虚拟机, 在eclipse.ini文件中要写成这样: -vm C:/Java/jre1.6.0/bin/javaw.exe -vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M 实际运行的结果可以通过Eclipse中“Help”-“About Eclipse SDK”窗口里面的“Configuration Details”按钮进行查看。 另外需要说明的是,Eclipse压缩包中自带的eclipse.ini文件内容是这样的: -showsplash org.eclipse.platform --launcher.XXMaxPermSize 256m -vmargs -Xms40m -Xmx256m 其中–launcher.XXMaxPermSize(注意最前面是两个连接线)跟-XX:MaxPermSize参数的含义基本是一样的,我觉得唯一的区别就是前者是eclipse.exe启动的时候设置的参数, 而后者是eclipse所使用的JVM中的参数。其实二者设置一个就可以了,所以这里可以把–launcher.XXMaxPermSize和下一行使用#注释掉。 4. 其他的启动参数。 如果你有一个双核的CPU,也许可以尝试这个参数: -XX:+UseParallelGC 让GC可以更快的执行。(只是JDK 5里对GC新增加的参数) 补充:   如果你的WEB APP下都用了大量的第三方jar,其大小超过了服务器jvm默认的大小,那么就会产生内存益出问题了。 解决方法: 设置MaxPermSize大小 可以在myelipse里选中相应的服务器比如tomcat5,展开里面的JDK子项页面,来增加服务器启动的JVM参数设置: -Xms128m -Xmx256m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m 或者手动设置MaxPermSize大小,比如tomcat, 修改TOMCAT_HOME/bin/catalina.bat,在echo "Using CATALINA_BASE: $CATALINA_BASE"上面加入以下行: JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m 建议:将相同的第三方jar文件移置到tomcat/shared/lib目录下,这样可以减少jar 文档重复占用内存 1.JVM内存管理的机制   内存空间划分为:Sun JDK在实现时遵照JVM规范,将内存空间划分为堆、JVM方法栈、方法区、本地方法栈、PC寄存器。 堆: 堆用于存储对象实例及数组值,可以认为Java中所有通过new创建的对象的内存都在此分配,Heap中对象所占用的内存由GC进行回收,在32位操作系统上最大为2GB,在64位操作系统上则没有限制,其大小可通过-Xms和-Xmx来控制,-Xms为JVM启动时申请的最小Heap内存,默认为物理内存的1/64但小于1GB;-Xmx为JVM可申请的最大Heap内存,默认为物理内存的1/4但小于1GB,默认当空余堆内存小于40%时,JVM会增大Heap到-Xmx指定的大小,可通过-XX:MinHeapFreeRatio=来指定这个比例;当空余堆内存大于70%时,JVM会减小Heap的大小到-Xms指定的大小,可通过-XX:MaxHeapFreeRatio=来指定这个比例,对于运行系统而言,为避免在运行时频繁调整Heap 的大小,通常将-Xms和-Xmx的值设成一样。 JVM方法栈: 为线程私有,其在内存分配上非常高效。当方法运行完毕时,其对应的栈帧所占用的内存也会自动释放。当JVM方法栈空间不足时,会抛出StackOverflowError的错误,在Sun JDK中可以通过-Xss来指定其大小。 方法区: 要加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息。方法区域也是全局共享的,在一定条件下它也会被GC,当方法区域要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。在Sun JDK中这块区域对应Permanet Generation,又称为持久代,默认最小值为16MB,最大值为64MB,可通过-XX:PermSize及-XX:MaxPermSize来指定最小值和最大值。 本地方法栈: 用于支持native方法的执行,存储了每个native方法调用的状态。在Sun JDK的实现中,和JVM方法栈是同一个。 PC寄存器: 占用的可能为CPU寄存器或操作系统内存。 2.Java堆和栈的区别   Java把内存划分成两种:一种是栈内存,一种是堆内存。   在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。   堆内存用来存放由new创建的对象和数组。在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,在栈中的这个特殊的变量就变成了数组或者对象的引用变量,以后就可以在程序中使用栈内存中的引用变量来访问堆中的数组或者对象,引用变量相当于为数组或者对象起的一个别名,或者代号。   引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放。而数组&对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放,数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因。但是在写程序的时候,可以人为的控制。 3.Java内存泄露和内存溢出   内存泄漏:分配出去的内存回收不了   内存溢出:指系统内存不够用了

posted @ 2016-06-21 21:58 youngturk 阅读(326) | 评论 (0)编辑 收藏

java面试题:如何解决内存溢出

http://zhidao.baidu.com/link?url=gQ4IAoIl07v0sxITrvasf8LwMwmFELou2d-6w11tqNHsNNdxQvDTg5f-EMlS0HSrAOG0mqw0DoBocICbuSfTvK 第一对所有的代码包括页面中的java代码都进行一遍彻底的回顾检查, 1.对那些静态(static)的对象要特别留神,特别是类型为Map,List,Set的,静态的变量会一直驻存在内存中,生命周期比较长,不会被垃圾器回收。 2.对于代码,要审查是否生成了大量的冗余的对象,还有一些逻辑业务处理的类, 算法是否过于复杂,调整算法,对于代码认真审查,再仔细重构一遍代码,能提高代码质量,提高程序运行稳定性。 3.Java中的内存溢出大都是因为栈中的变量太多了。其实内存有的是。建议不用的尽量设成null以便回收,多用局部变量,少用成员变量。 1),变量所包含的对象体积较大,占用内存较多。 2),变量所包含的对象生命周期较长。 3),变量所包含的对象数据稳定。 4),该类的对象实例有对该变量所包含的对象的共享需求。 4.在我的程序中对静态变量的优化后,使程序占用内存量至少提升了5k-10k。所以也不容忽视。 第二还有就是String类相关的东西: 1.字符串累加的时候一定要用StringBuffer的append方法,不要使用+操作符连接两个字符串。差别很大。而且在循环或某些重复执行的动作中不要去创建String对象,因为String对象是要用StringBuffer对象来处理的,一个String对象应该是产生了 3个对象(大概是这样:))。 2.字符串length()方法来取得字符串长度的时候不要把length放到循环中,可以在循环外面对其取值。(包括vector的size方法)。特别是循环次数多的时候,尽量把length放到循环外面。 int size = xmlVector.size(); for (int i = 2; i < size; i++) { ... } 3 .写代码的时候处理内存溢出 try{ //do sth .... }catch (outofmemoryerror e){//可以用一个共通函数来执行. system.out.print (“no memory! ”); system.gc(); //do sth again .... }   4.对于频繁申请内存和释放内存的操作,还是自己控制一下比较好,但是System.gc()的方法不一定适用,最好使用finallize强制执行或者写自己的finallize方法。 Java 中并不保证每次调用该方法就一定能够启动垃圾收集,它只不过会向JVM发出这样一个申请,到底是否真正执行垃圾收集,一切都是个未知数。 1.优化程序2.改进算法3.增加jvm内存分配

posted @ 2016-06-21 21:37 youngturk 阅读(307) | 评论 (0)编辑 收藏

jquery中ajax处理跨域的三大方式 ,jQuery学习之jQuery Ajax用法详解

http://www.jb51.net/article/77470.htm http://www.php100.com/html/program/jquery/2013/0905/6004.html

posted @ 2016-06-20 23:10 youngturk 阅读(150) | 评论 (0)编辑 收藏

我的理解--关于jmx

http://bhsc-happy.iteye.com/blog/678163
http://www.cnblogs.com/Javame/p/3881187.html
JMX Java Management Extensions,Java管理扩展,初步看了些资料,以为是专门管理,监控jvm的一些信息的,特别是visual VM这个监控jvm的东西,还有一个添加JMX连接的时候(我自己想错了,那样的话应该叫jvm Management Extensions),其实他能使得基于java语言开发的程序能被管理,并且是可扩展的。 Jdk以前是通过JVMPI之类来监测Java程序运行中的jvm和系统的一系列情况,现在通过jmx就可以做到,这是通过java.lang.management 包来实现的,这个包是 JMX 在 JDK方面 的一个应用,并不是表示jmx就是一个监控jvm的东西。 我们可以用jmx来监控我们的系统,通过公布API的方式,但是,这里采用监控这个词,也是受了前面的例子的影响,实际上,个人觉得,就可以用jmx来开发我们的系统。 现在的jboss,hibernate,tomcat各种应用都号称实现了JMX规范,将可管理,可调用的MBean注册到MBeanServer中,通过一种类似“web服务”的方式公布出去,并且伴有一个名字,可以通过该名字找到该MBean。并且,这里的MBean是可以被管理的,说到这里又想到了OSGI。 JMX与Web Service 个人认为,我们实现JMX规范,将东西发布出去,和通过web Service的方式是很类似的,也是可以远程调用的,只是相对的web Service的方式更加SOA一些,不过JMX号称也要提供对非java客户端的支持,也就是跨语言了吧。。。 现在的JMX连接方式: JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/server"); JMXConnector jmxc = JMXConnectorFactory.connect(url, null); 看了下源码,貌似还是通过RMI来实现的,不知道它要怎么实现非java客户端支持。 从这里,我觉得JMX可以实现的,我们也都可以通过web Service实现,只是看在它有个“M”上,以后如果有什么系统管理,监控方面的,可以考虑使用它,也许开发,个人觉得还是使用web service好一些。 说到这里,感觉OSGI与JMX也好像,在看到JMX能够对MBean进行管理的时候,我就觉得跟OSGI很像,OSGI管理的是Bundle,找了找资源,原来早就有人考虑过了: http://teamojiao.iteye.com/blog/438334 顺便,在查资料的时候,发现一个东西, if your question means, how to manage an OSGi runtime with JMX, you should have a look at MAEXO (http://code.google.com/p/maexo/). With MAEXO bundles up and running you will transparently get MBeans for a fair amount of services of the OSGi runtime as well as MBeans for your own services and bundles. Just have a look at the screencast. 摘一些话:仅做参考 <网友回复> 一个大系统中,各内部模块系统之间的基于接口方式的互相调用和治理,使用jmx是最佳方案. 带来的好处是 1.面向接口,远程调用对于开发人员是透明的,模块在调用jmx接口时,与调用本地方法几乎相同. 2.可视化的治理界面, 通过 Jconsole等jmx客户端,可以实时监控系统,并且可实时调用方法进行某些操作. 典型应用场景:  某聊天系统,一台服务器作为 在线用户列表服务器 A1, n台服务器为用户提供聊天业务处理 N1 ,N2,N3..., 一台服务器作为后台治理系统A2.  系统治理员现在进行下面这样一个操作,察看某用户是否在线,找到该用户,发现其在线,则将该用户加入黑名单,并踢下线. 对应的jmx接口可以由以下几个:  A1为A2提供查询在线用户jmx接口,加入黑名单接口,kickout接口, A1为N1..等服务器提供以下接口: 注册业务服务器,添加在线用户.查找黑名单用户 N1...到N3为A1提供kickout接口. 因此在上面的踢下线操作,则由用户在A2的web界面发出,交由A1执行,A1记录黑名单之后,再找到用户所在业务服务器调用N1提供的接口让用户下线. 以上情形是在生产环境下的部署,而在开发工作,则可以将A1,A2,N...N3等功能合并在一个应用中调试. 由于使用的是jmx接口,在本地调试合并之后,可以直接调用应用内部接口方法. 这样借助jmx实现的应用模块的灵活组装与拆分,使得系统的可以根据负载需要,根据性能情况,灵活的拆分和整合部署分布式的应用. 替代方案,选择webservice,xmlrpc等,但是这些都需要手工编写或用工具生成大量的代码来辅助完成接口间的java对象序列化 。 经典jmx案例: 1.Jboss.使用jmx治理内部的各个service。 2. 基于java的开源网管软件 Hyperic HQ ,通过jmx与各被治理资源进行通讯和信息采集. <网友回复>JMX是一个治理的框架。 当我们想使用JMX的时候,就要问,我们的系统当中有需要监控治理的资源或者对象吗?实事求是一点,我们不能为了想使用一个高端的技术,就歪曲系统的本来面目。 假如第一个问题是肯定的,接下来就是看这些资源是否有生命周期。 经典案例:jboss就是将所有可部署的组件作为资源来治理,这些组建都有其生命周期。这个理念甚至延伸到了其系统内部,将其内部的服务作为组件纳入到 JMX中来,成就了jboss基于jmx的微内核系统。

posted @ 2016-06-20 09:40 youngturk 阅读(149) | 评论 (0)编辑 收藏

java socket编程

http://www.cnblogs.com/linzheng/archive/2011/01/23/1942328.html
http://www.ibm.com/developerworks/cn/linux/l-cn-socketftp/一,网络编程中两个主要的问题

一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输。

在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一地确定Internet上的一台主机。

而TCP层则提供面向应用的可靠(tcp)的或非可靠(UDP)的数据传输机制,这是网络编程的主要对象,一般不需要关心IP层是如何处理数据的。

目前较为流行的网络编程模型是客户机/服务器(C/S)结构。即通信双方一方作为服务器等待客户提出请求并予以响应。客户则在需要服务时向服务器提 出申请。服务器一般作为守护进程始终运行,监听网络端口,一旦有客户请求,就会启动一个服务进程来响应该客户,同时自己继续监听服务端口,使后来的客户也 能及时得到服务。

二,两类传输协议:TCP;UDP

TCP是Tranfer Control Protocol的 简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个socket之间必须建 立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送 或接收操作。

UDP是User Datagram Protocol的简称,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。

比较:

UDP:1,每个数据报中都给出了完整的地址信息,因此无需要建立发送方和接收方的连接。

            2,UDP传输数据时是有大小限制的,每个被传输的数据报必须限定在64KB之内。

           3,UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方

TCP:1,面向连接的协议,在socket之间进行数据传输之前必然要建立连接,所以在TCP中需要连接

                时间。

            2,TCP传输数据大小限制,一旦连接建立起来,双方的socket就可以按统一的格式传输大的  

                    数据。

             3,TCP是一个可靠的协议,它确保接收方完全正确地获取发送方所发送的全部数据。

应用:

1,TCP在网络通信上有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠地传输。但是可靠的传输是要付出代价的,对数据内容正确性的检验必然占用计算机的处理时间和网络的带宽,因此TCP传输的效率不如UDP高。

2,UDP操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序。例如视频会议系统,并不要求音频视频数据绝对的正确,只要保证连贯性就可以了,这种情况下显然使用UDP会更合理一些。

三,基于Socket的java网络编程

1,什么是Socket

网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。Socket通常用来实现客户方和服务方的连接。Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。

但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。

2,Socket通讯的过程

Server端Listen(监听)某个端口是否有连接请求,Client端向Server 端发出Connect(连接)请求,Server端向Client端发回Accept(接受)消息。一个连接就建立起来了。Server端和Client 端都可以通过Send,Write等方法与对方通信。

对于一个功能齐全的Socket,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:

  (1) 创建Socket;

  (2) 打开连接到Socket的输入/出流;

  (3) 按照一定的协议对Socket进行读/写操作;

  (4) 关闭Socket.(在实际应用中,并未使用到显示的close,虽然很多文章都推荐如此,不过在我的程序中,可能因为程序本身比较简单,要求不高,所以并未造成什么影响。)

3,创建Socket

创建Socket

java在包java.net中提供了两个类Socket和ServerSocket,分别用来表示双向连接的客户端和服务端。这是两个封装得非常好的类,使用很方便。其构造方法如下:

  Socket(InetAddress address, int port);

  Socket(InetAddress address, int port, boolean stream);

  Socket(String host, int prot);

  Socket(String host, int prot, boolean stream);

  Socket(SocketImpl impl)

  Socket(String host, int port, InetAddress localAddr, int localPort)

  Socket(InetAddress address, int port, InetAddress localAddr, int localPort)

  ServerSocket(int port);

  ServerSocket(int port, int backlog);

  ServerSocket(int port, int backlog, InetAddress bindAddr)

  其中address、host和port分别是双向连接中另一方的IP地址、主机名和端 口号,stream指明socket是流socket还是数据报socket,localPort表示本地主机的端口号,localAddr和 bindAddr是本地机器的地址(ServerSocket的主机地址),impl是socket的父类,既可以用来创建serverSocket又可 以用来创建Socket。count则表示服务端所能支持的最大连接数。例如:学习视频网 http://www.xxspw.com

  Socket client = new Socket("127.0.01.", 80);

  ServerSocket server = new ServerSocket(80);

  注意,在选择端口时,必须小心。每一个端口提供一种特定的服务,只有给出正确的端口,才 能获得相应的服务。0~1023的端口号为系统所保留,例如http服务的端口号为80,telnet服务的端口号为21,ftp服务的端口号为23, 所以我们在选择端口号时,最好选择一个大于1023的数以防止发生冲突。

  在创建socket时如果发生错误,将产生IOException,在程序中必须对之作出处理。所以在创建Socket或ServerSocket是必须捕获或抛出例外。

4,简单的Client/Server程序

1. 客户端程序

  import java.io.*;

  import java.net.*;

  public class TalkClient {

    public static void main(String args[]) {

      try{

        Socket socket=new Socket("127.0.0.1",4700);

        //向本机的4700端口发出客户请求

        BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));

        //由系统标准输入设备构造BufferedReader对象

        PrintWriter os=new PrintWriter(socket.getOutputStream());

        //由Socket对象得到输出流,并构造PrintWriter对象

        BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));

        //由Socket对象得到输入流,并构造相应的BufferedReader对象

        String readline;

        readline=sin.readLine(); //从系统标准输入读入一字符串

        while(!readline.equals("bye")){

        //若从标准输入读入的字符串为 "bye"则停止循环

          os.println(readline);

          //将从系统标准输入读入的字符串输出到Server

          os.flush();

          //刷新输出流,使Server马上收到该字符串

          System.out.println("Client:"+readline);

          //在系统标准输出上打印读入的字符串

          System.out.println("Server:"+is.readLine());

          //从Server读入一字符串,并打印到标准输出上

          readline=sin.readLine(); //从系统标准输入读入一字符串

        } //继续循环

        os.close(); //关闭Socket输出流

        is.close(); //关闭Socket输入流

        socket.close(); //关闭Socket

      }catch(Exception e) {

        System.out.println("Error"+e); //出错,则打印出错信息

      }

  }

}

 2. 服务器端程序

  import java.io.*;

  import java.net.*;

  import java.applet.Applet;

  public class TalkServer{

    public static void main(String args[]) {

      try{

        ServerSocket server=null;

        try{

          server=new ServerSocket(4700);

        //创建一个ServerSocket在端口4700监听客户请求

        }catch(Exception e) {

          System.out.println("can not listen to:"+e);

        //出错,打印出错信息

        }

        Socket socket=null;

        try{

          socket=server.accept();

          //使用accept()阻塞等待客户请求,有客户

          
//请求到来则产生一个Socket对象,并继续执行

        }catch(Exception e) {

          System.out.println("Error."+e);

          //出错,打印出错信息

        }

        String line;

        BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));

         //由Socket对象得到输入流,并构造相应的BufferedReader对象

        PrintWriter os=newPrintWriter(socket.getOutputStream());

         //由Socket对象得到输出流,并构造PrintWriter对象

        BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));

         //由系统标准输入设备构造BufferedReader对象

        System.out.println("Client:"+is.readLine());

        //在标准输出上打印从客户端读入的字符串

        line=sin.readLine();

        //从标准输入读入一字符串

        while(!line.equals("bye")){

        //如果该字符串为 "bye",则停止循环

          os.println(line);

          //向客户端输出该字符串

          os.flush();

          //刷新输出流,使Client马上收到该字符串

          System.out.println("Server:"+line);

          //在系统标准输出上打印读入的字符串

          System.out.println("Client:"+is.readLine());

          //从Client读入一字符串,并打印到标准输出上

          line=sin.readLine();

          //从系统标准输入读入一字符串

        }  //继续循环

        os.close(); //关闭Socket输出流

        is.close(); //关闭Socket输入流

        socket.close(); //关闭Socket

        server.close(); //关闭ServerSocket

      }catch(Exception e){

        System.out.println("Error:"+e);

        //出错,打印出错信息

      }

    }

  }

5,支持多客户的client/server程序

前面的Client/Server程序只能实现Server和一个客户的对话。在实际应用 中,往往是在服务器上运行一个永久的程序,它可以接收来自其他多个客户端的请求,提供相应的服务。为了实现在服务器方给多个客户提供服务的功能,需要对上 面的程序进行改造,利用多线程实现多客户机制。服务器总是在指定的端口上监听是否有客户请求,一旦监听到客户请求,服务器就会启动一个专门的服务线程来响 应该客户的请求,而服务器本身在启动完线程之后马上又进入监听状态,等待下一个客户的到来。

posted @ 2016-06-19 22:20 youngturk 阅读(159) | 评论 (0)编辑 收藏

java 环境变量配置

1. java_home C:\jdk1.6.0_30 2. Path ;%java_home%\bin 3. classpath .;%java_home%\lib\dt.jar;%java_home%\lib\tools.jar

posted @ 2016-06-19 22:18 youngturk 阅读(352) | 评论 (0)编辑 收藏

JVM介绍

http://www.cnblogs.com/sunada2005/p/3577799.html

posted @ 2016-06-19 22:11 youngturk 阅读(145) | 评论 (0)编辑 收藏

关于Tomcat 6的热部署和热加载 转

http://greemranqq.iteye.com/blog/1774258 
http://www.cnblogs.com/-lpf/p/4317281.html
我在项目开发过程中,经常要改动JAVA/JSP 文件,但是又不想从新启动服务器(服务器从新启动花时间),想直接获得(debug)结果.有两种方式热部署 和热加载:

 

1.热加载:在server.xml -> context 属性中 设置 reloadable="true"

 

Java代码  收藏代码
  1. <Context docBase="xxx" path="/xxx" reloadable="true"/>  

    

 

2. 热部署:在server.xml -> context 属性中 设置  autoDeploy="true"

  

Java代码  收藏代码
  1. <Context docBase="xxx" path="/xxx" autoDeploy="true"/>  

 

3.区别:

      热加载:服务器会监听 class 文件改变,局部进行加载,不清空session ,不释放内存。开发中用的多,但是要考虑内存溢出的情况。

 

      热部署: 整个项目从新部署,包括你从新打上.war 文件。 会清空session ,释放内存。项目打包的时候用的多。

 

也可以通过Eclipse上设置实现上述配置文件的修改 

Eclipse的工程名右键: properties->Tomcat->General->Make this context as reloadable(reloadable="true")不要选中 Eclipse的工程名右键:Tomcat project->Update Context Definition

 

注意:source 属性有些版本不支持,容易出错,去掉就行 

二。

不重启Tomcat有两种方式:热部署、热加载 
  热部署:容器状况在运行时重新部署整个项目。这类环境下一般整个内存会清空,重新加载,这类方式 
  有可能会造成sessin丢失等环境。tomcat 6确实可以热部署了,而且对话也没丢. 
  热加载:最好是在调试过程中使用,免患上整个项目加载,Debug标准样式支持热加载。容器状况在运行时重 
  新加载转变编译后的类。在这类环境下内存不会清空,sessin不会丢失,但容易造成内存溢出,或者找不到方 
  法。一般转变类的布局和模型就会有异常,在已经有的变量和方法中转变是不会出问题的(Eclipse、 
  MyEclipse8、JBuilder、IntelliJ IDEA…)。 
  常用的一定第二种:热加载了,设置如下! 
  在tomcat的conf中的server.xml中的host设置中添加<Context path="/test" 
  docBase="D:/develop/test" 
  debug="0" privileged="true" reloadable="true"/> 
  reloadable="true" !最重要 
  它内里有很多属性,意义如下: 
  1>path:指定拜候该web应用的URL进口; 
  2>docBase:指定web应用的文件路径,可以给定绝对路径,也可以给定相对于<Host>的appBase属性【默认 
  指向tomcat的webapps】的相对于径;要是Web应用是个war文件,则指定war文件的路径。 
  3>className:指定使成为事实Context组件的Java类的名字,这个Java类必须使成为事实org.apache.catalina.Context 
  接口,该属性的默认值为org.apache.catalina.StandardContext。 
  4>reloadable:要是这个属性设置为true,Tomcat服务器在运行状况下会监视在WEB-INF/classess和WEB- 
  INF/lib目次下的class文件的改动,以及监视web应用的WEB-INF/web.xml文件的改动。要是检测到的class 
  文件或者web.xml文件被更新,服务器会自动加载Web应用。该属性的默认值为false.在web应用的开发和调 
  试阶段,把reloadable设为true,可以方便对web应用的调试。在web应用正式发布阶段,把reloadable设为 
  false,可以减低tomcat的运行负荷,提高Tomcat的运行性能。 
  5>cachingAllowed:要是为true,标示允许启用静态资源的缓存。使用缓存能提高拜候静态资源的效率。 
  tomcat把那一些时常被客户端拜候的静态资源(如:HTML文档、图片文件和声响文件等)放在缓存中,当客户再 
  次拜候有关静态资源时,Tomcat只需直接从缓存中读取相关数据,无须反复读取文件系统中的文件。该属 
  性的默认值为true. 
  6>cacheMaxSize:设定静态资源的缓存的最大容量,以K为单元。要是,要是该属性为100,表示100K,默认 
  为10240(即10M)。 
  7>workDir:指定web应用的工作目次。Tomcat在运行时会把与这个web应用相关的临应试文章件放在此目次下。 
  8>uppackWar:要是此项设为true,表示将把web应用的war文件睁开为开放目次布局后再运行。要是设为 
  false,则直接运行war文件。该属性的默认值为true。 
  同志们,使用tomcat6.0的注意了啊。当你使用我的方法设置tomcat后,你的myeclipse报如下错误时,不要惊慌,这是正确的,且听我解释。 
  console报错: 
  警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property ' debug' to '0' did not find a matching property. 这是由于你使用的是tomcat6.0,由于它路程经过过程其他途径对debug="0"这个属性进行了使成为事实,所以这搭不能再有此属性。你只要将它去掉,就能够没事了启动了。 也就是说去掉debug="0“,万事OK,呵呵。 


(转)

-------------------------------------------------------------

针对需要重新启动tomcat的服务,重新启动方式为:

安装版:tomcat/bin/shotdown.bat      关闭tomcat服务

          tomcat/bin/startup.bat         开启tomcat服务

或者-->我的电脑-->管理-->服务和应用程序/服务-->找到Apache Tomcat重启

posted @ 2016-06-19 21:03 youngturk 阅读(273) | 评论 (0)编辑 收藏

apache tomcat mod_js配置整合,

http://blog.sina.com.cn/s/blog_3c9872d00102w00y.html
Apache与Tomcat整合应用是一个老话题,不算新技能,但对非运维人员在配置过程中或许也会遇到一些问题。这里只是把自己多回配置的过程做一个摘录,供自己翻阅并望对过路的人有用。
Apache是当下在Windows、Unix、Linux 等操作系统中最流行的Web服务器软件之一,其反应速度快、运行效率高,不仅支持HTML等静态页面,在加载插件后也可支持 PHP 页面等。Tomcat是Apache软件基金协会与Sun公司联合开发的Web服务器,除支持HTML静态页面外,还是JSP、Servlet等JAVA WEB应用的服务器。在相同运行环境下,Tomcat对静态页面的反应速度没有Apache灵敏,整合 Apache与Tomcat能使系统运行于一个良好环境下,实现JAVA的动态与静态页面分离,不仅让系统更安全,同时也可提高系统效率。

一、JAVA应用基础架构

通用的JAVA应用架构如下,包括WEB Server、APP Server和DB Server三个部分:
Apache和Tomcat整合配置实现JAVA应用的“动静”分离
1、WEB Server
WEB Server置于企业防火墙外,这个防火墙也可以认为是一个CISCO路由器,在CISCO路由器上开放两个端口为:80和443,其中:
80端口:用于正常的http访问
443端口:用于https访问,即如果你在ie里打入https://xxx.xxx.xx这样的地址,默认走的是443这个端口
WebServer专门用于解析HTML、JS(JavaScript)、CSS、JPG/GIF等图片格式文件、TXT、VBSCRIPT、PHP等“静态”网页内容。
2、APP Server
APP Server置于企业防火墙内,它和Web Server之间的连接必须且一定为内部IP连接。App Server用于解析我们的任何需要Java编译器才能解析的“动态”网页,其实App Server本身也能解析任何静态网页的。在应用中我们这样来想一下:我们让负责专门解析静态网页的Web Server来解析html等内容,而让App Server专门用于解析任何需要Java编译器才能解析的东西,让它们各司其职。这样作的好处:
  1)为App Server“减压”,同时也提高了性能;
  2)不用再把8080这个端口暴露在internet上,也很安全,毕竟我们的App Server上是有我们的代码的,就算是编译过的代码也容易被“反编译”,这是很不安全的;
  3)为将来进一步的“集群扩展”打好了基础。
3、DB Server
 比方说我们用MySQL,它需要通过3306与App Server进行连接,那么这个1521我们称为数据库连接端口,如果把它暴露在Internet上就比较危险,就算密码很复杂,但 对于高明的黑客来说,要攻破你的口令也只是时间上的问题而己。因此我们把我们的DB Server也和App Server一样,置于内网的防火墙,任何的DB连接与管理只能通过内网来访问。
二、系统安装与配置
系统安装包括MySQL的安装,WEB Server即Apache的安装,App Server即Tomcat的安装。关于这三个系统安装网上相关的文档很多,此处略去。以下主要摘录需要重点配置的内容。
1、Apache的配置
做技术的人应该都会Apache的基础配置,如果不会确实需要学一学。
Apache的配置主要集中在httpd.conf文件中,它位于Apache的安装目录下,比如我的是在“C:\webserver\apache\apache22\conf”目录下。用Ultraedit或Notepad++编辑器打开文件,通常需要修改的内容包括ServerName、DocumentRoot、VirtualHost内容等。此处我修改的内容包括:
1)DocumentRoot原目录为C:/webserver/apache/apache22/htdocs,修改为D:/WWW/apache/htdocs,将网站发布路径与Apache安装路径分开;
2)找到如下红色标示内容:
    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
    deny from all
把这个”deny from all”改成”allow fromall’。
    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
    allow from all
以免访问Apache根目录下的文件时出现以下错误提示:
Apache和Tomcat整合配置实现JAVA应用的“动静”分离
3)再找到下面这样的行
Options FollowSymLinks indexes
把它注掉改成下面这样
#Options FollowSymLinks indexes
Options None
以免在访问Apache目录时出现直接列表显示子目录或目录下文件的不安全情况,如下图样子:
Apache和Tomcat整合配置实现JAVA应用的“动静”分离
以上配置修改完成后重启Apache服务,保证要能正常运行。
三、Apache与Tomcat的整合配置
Apache(Web Server)负责处理HTML静态内容,Tomcat(App Server)负责处理动态内容;原理图如下:
Apache和Tomcat整合配置实现JAVA应用的“动静”分离
上述架构的原理是: 在Apache中装载一个模块,这个模块叫mod_jk; Apache通过80端口负责解析任何静态web内容; 任何不能解析的内容,用表达式告诉mod_jk,让mod_jk派发给相关的App Server去解释。
因此,首先把 mod_jk-1.2.31-httpd-2.2.3(可从网上搜索下载该模块,如http://download.csdn.net/detail/shangkaikuo/4494837)拷贝到 "/Apache2.2/modules" 目录下。接下来:
1、添加workers.properties文件
在 “/Tomcat 8.0/conf ” 文件夹下(也可以是其它目录下)增加 workers.properties 文件,输入以下内容。(将其中相应目录替换成自己本地tomcat或jre安装目录)
 #让mod_jk模块认识Tomcat
 workers.tomcat_home=d:/webserver/tomcat/tomcat8
 #让mod_jk模块认识JRE
 workers.java_home=C:/java/jdk1.8.0_45/jre
 #指定文件路径分割符
 ps=/
 ##
 #工作端口,此端口应该与server.xml中Connector元素的AJP/1.3协议所使用的端口相匹配
 worker.list=AJP13
 worker.AJP13.port=8009
 #Tomcat服务器的地址
 worker.AJP13.host=localhost
 #类型
 worker.AJP13.type=ajp13
 #负载平衡因数
 worker.AJP13.lbfactor=1

**注意:worker.list=AJP13中,AJP13为自定义名称,但此名称必须与下文所述的 “/Apache 2.2/conf/httpd.conf ” 文件中,JkMount指令对应的名称相匹配。
2、httpd.conf文件中添加配置内容
加入workers.properties文件后,可修改 “/Apache 2.2/conf/httpd.conf ” 文件,加入以下配置,注意JkMount指令中的变量必须与worker.list所配置的名称相同。

# 此处mod_jk-1.2.31-httpd-2.2.3文件为你下载的文件
LoadModule  jk_module  modules/mod_jk-1.2.31-httpd-2.2.3.so
# 指定tomcat监听配置文件地址
JkWorkersFile  "C:/webserver/tomcat/tomcat8/conf/workers.properties"
#JkWorkersFile  "C:/webserver/apache/apache22/conf/workers.properties"
# 指定日志存放位置
JkLogFile  "C:/webserver/tomcat/tomcat8/logs/mod_jk2.log"
JkLogLevel  info
-virtualhost *-
    ServerName  localhost
    DocumentRoot  "C:/webserver/tomcat/tomcat8/webapps"
    DirectoryIndex  index.html index.htm index.jsp index.action
    ErrorLog  logs/shsc-error_log.txt
    CustomLog  logs/shsc-access_log.txt common
    JkMount  /*WEB-INF AJP13
    JkMount  /*j_spring_security_check AJP13
    JkMount  /*.action AJP13
    JkMount  /servlet/* AJP13
    JkMount  /*.jsp AJP13
    JkMount  /*.do AJP13
    JkMount  /*.action AJP13
-/virtualhost-

上述配置中的红色内容是为了告诉Apache哪些交给Tomcat去处理,其它的都交由Apache自身去处理。
其中绿色的两句比较关键,分别告诉:Apache载入一个额外的插件,用于连接tomcat;  连接时的配置参数描述位于Tomcat安装目录的/conf目录下的一个叫workers.properties文件中,mod_jk一般使用ajp13协议连接,使用的是tomcat的8009端口。
完成以上配置后,重启 Apache、Tomcat。此时Apache、Tomcat的默认目录为 "C:/Program Files/Apache Software Foundation/Tomcat 7.0/webapps ”,Apache使用默认的80端口、Tomcat端口改成1080或其它非8080默认端口(修改是为了安全,也可以不用修改)。在Tomcat默认目录下添加test目录,在该目录下加入index.jsp页面,然后通过http://localhost/test/index.jsp试试是否可以正常访问,如页面可正常访问,证明整合配置已经成功。
至此,似乎整个配置工作已经完成,但是如果你想试着把静态的HTML页面放到Apache的htdocs发布目录下,把JSP等动态内容放到Tomcat的webapps目录下(该目录下不存放*.html文件),然后通过http://localhost/index.html想访问Apache目录下的内容,你会发现404之类的不能访问的错误。如何解决,这里暂时卖个关子.......如果你能看出问题,能容易解决掉,就诚挚为你点个赞!
 

posted @ 2016-06-19 20:42 youngturk 阅读(208) | 评论 (0)编辑 收藏

关于Tomcat和Tomcat的面试问题

http://www.jfox.info/guan-yu-Tomcat-he-Tomcat-de-mian-shi-wen-ti 
http://www.jfox.info/guan-yu-Tomcat-he-Tomcat-de-mian-shi-wen-ti

关于Tomcat和Tomcat的面试问题

一、Tomcat的缺省是多少,怎么修改

Tomcat的缺省端口号是8080.
修改Tomcat端口号:
1.找到Tomcat目录下的conf文件夹
2.进入conf文件夹里面找到server.xml文件
3.打开server.xml文件
4.在server.xml文件里面找到下列信息
maxThreads=”150″ minSpareThreads=”25″ maxSpareThreads=”75″
enableLookups=”false” redirectPort=”8443″ acceptCount=”100″
connectionTimeout=”20000″ disableUploadTimeout=”true” />
5.把port=”8080″改成port=”8888″,并且保存
6.启动Tomcat,并且在IE浏览器里面的地址栏输入http://127.0.0.1:8888/

7、tomcat默认采用的BIO模型,在几百并发下性能会有很严重的下降。tomcat自带还有NIO的模型,另外也可以调用APR的库来实现操作系统级别控制。
  NIO模型是内置的,调用很方便,只需要将上面配置文件中protocol修改成 org.apache.coyote.http11.Http11NioProtocol,重启即可生效。如下面的参数配置,默认的是HTTP/1.1。
    <Connector port=”8080″  
               protocol=”org.apache.coyote.http11.Http11NioProtocol” 
               connectionTimeout=”20000″ 
               redirectPort=”8443″  
               maxThreads=”500″  
               minSpareThreads=”20″ 
               acceptCount=”100″
               disableUploadTimeout=”true”
               enableLookups=”false”  
               URIEncoding=”UTF-8″ />

二、tomcat 如何优化?

 1、优化连接配置.这里以tomcat7的参数配置为例,需要修改conf/server.xml文件,修改连接数,关闭客户端dns查询。

参数解释:

 URIEncoding=”UTF-8″ :使得tomcat可以解析含有中文名的文件的url,真方便,不像apache里还有搞个mod_encoding,还要手工编译

 maxSpareThreads : 如果空闲状态的线程数多于设置的数目,则将这些线程中止,减少这个池中的线程总数。

 minSpareThreads : 最小备用线程数,tomcat启动时的初始化的线程数。

 enableLookups : 这个功效和Apache中的HostnameLookups一样,设为关闭。

 connectionTimeout : connectionTimeout为网络连接超时时间毫秒数。

 maxThreads : maxThreads Tomcat使用线程来处理接收的每个请求。这个值表示Tomcat可创建的最大的线程数,即最大并发数。

 acceptCount : acceptCount是当线程数达到maxThreads后,后续请求会被放入一个等待队列,这个acceptCount是这个队列的大小,如果这个队列也满了,就直接refuse connection

 maxProcessors与minProcessors : 在 Java中线程是程序运行时的路径,是在一个程序中与其它控制线程无关的、能够独立运行的代码段。它们共享相同的地址空间。多线程帮助程序员写出CPU最 大利用率的高效程序,使空闲时间保持最低,从而接受更多的请求。

通常Windows是1000个左右,Linux是2000个左右。

 useURIValidationHack:

我们来看一下tomcat中的一段源码:

【security】

        if (connector.getUseURIValidationHack()) {

            String uri = validate(request.getRequestURI());

            if (uri == null) {

                res.setStatus(400);

                res.setMessage(“Invalid URI”);

                throw new IOException(“Invalid URI”);

            } else {

                req.requestURI().setString(uri);

                // Redoing the URI decoding

                req.decodedURI().duplicate(req.requestURI());

                req.getURLDecoder().convert(req.decodedURI(), true);

可以看到如果把useURIValidationHack设成”false”,可以减少它对一些url的不必要的检查从而减省开销。

 enableLookups=”false” : 为了消除DNS查询对性能的影响我们可以关闭DNS查询,方式是修改server.xml文件中的enableLookups参数值。

 disableUploadTimeout :类似于Apache中的keeyalive一样

给Tomcat配置gzip压缩(HTTP压缩)功能

compression=”on” compressionMinSize=”2048″

compressableMimeType=”text/html,text/xml,text/javascript,text/css,text/plain”

HTTP 压缩可以大大提高浏览网站的速度,它的原理是,在客户端请求网页后,从服务器端将网页文件压缩,再下载到客户端,由客户端的浏览器负责解压缩并浏览。相对于普通的浏览过程HTML,CSS,Javascript , Text ,它可以节省40%左右的流量。更为重要的是,它可以对动态生成的,包括CGI、PHP , JSP , ASP , Servlet,SHTML等输出的网页也能进行压缩,压缩效率惊人。

1)compression=”on” 打开压缩功能

2)compressionMinSize=”2048″ 启用压缩的输出内容大小,这里面默认为2KB

3)noCompressionUserAgents=”gozilla, traviata” 对于以下的浏览器,不启用压缩

4)compressableMimeType=”text/html,text/xml” 压缩类型

最后不要忘了把8443端口的地方也加上同样的配置,因为如果我们走https协议的话,我们将会用到8443端口这个段的配置,对吧?

<!–enable tomcat ssl–>

    <Connector port=”8443″ protocol=”HTTP/1.1″

               URIEncoding=”UTF-8″  minSpareThreads=”25″ maxSpareThreads=”75″

          enableLookups=”false” disableUploadTimeout=”true” connectionTimeout=”20000″

          acceptCount=”300″  maxThreads=”300″ maxProcessors=”1000″ minProcessors=”5″

          useURIValidationHack=”false”

                    compression=”on” compressionMinSize=”2048″

                    compressableMimeType=”text/html,text/xml,text/javascript,text/css,text/plain”

                SSLEnabled=”true”

           scheme=”https” secure=”true”

           clientAuth=”false” sslProtocol=”TLS”

           keystoreFile=”d:/tomcat2/conf/shnlap93.jks” keystorePass=”aaaaaa”

      />

好了,所有的Tomcat优化的地方都加上了。

2、优化JDK
Tomcat默认可以使用的内存为128MB,Windows下,在文件{tomcat_home}/bin/catalina.bat,Unix下,在文件$CATALINA_HOME/bin/catalina.sh的前面,增加如下设置:
JAVA_OPTS=”‘$JAVA_OPTS” -Xms[初始化内存大小] -Xmx[可以使用的最大内存]

设置环境变量:export JAVA_OPTS=””$JAVA_OPTS” -Xms[初始化内存大小] -Xmx[可以使用的最大内存]”
一般说来,你应该使用物理内存的 80% 作为堆大小。如果本机上有Apache服务器,可以先折算Apache需要的内存,然后修改堆大小。建议设置为70%;建议设置[[初始化内存大小]等于[可以使用的最大内存],这样可以减少平凡分配堆而降低性能。
本例使用加入环境变量的方式:
# vi /etc/profile
加入:export JAVA_OPTS=””$JAVA_OPTS” -Xms700 —Xmx700
# source /etc/profile

【参数说明】

-Xms 是指设定程序启动时占用内存大小。一般来讲,大点,程序会启动的 快一点,但是也可能会导致机器暂时间变慢。

-Xmx 是指设定程序运行期间最大可占用的内存大小。如果程序运行需要占 用更多的内存,超出了这个设置值,就会抛出OutOfMemory 异常。

-Xss 是指设定每个线程的堆栈大小。这个就要依据你的程序,看一个线程 大约需要占用多少内存,可能会有多少线程同时运行等。

-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64 。

-XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。

三、tomcat 有那几种Connector 运行模式?

tomcat的运行模式有3种.修改他们的运行模式.3种模式的运行是否成功,可以看他的启动控制台,或者启动日志.或者登录他们的默认页面http://localhost:8080/查看其中的服务器状态。

1)bio

默认的模式,性能非常低下,没有经过任何优化处理和支持.

2)nio

利用java的异步io护理技术,no blocking IO技术.

想运行在该模式下,直接修改server.xml里的Connector节点,修改protocol为

 <Connector port=”80″ protocol=”org.apache.coyote.http11.Http11NioProtocol”
    connectionTimeout=”20000″
    URIEncoding=”UTF-8″
    useBodyEncodingForURI=”true”
    enableLookups=”false”
    redirectPort=”8443″ />

启动后,就可以生效。

3)apr

安装起来最困难,但是从操作系统级别来解决异步的IO问题,大幅度的提高性能.

必须要安装apr和native,直接启动就支持apr。下面的修改纯属多余,仅供大家扩充知识,但仍然需要安装apr和native

如nio修改模式,修改protocol为org.apache.coyote.http11.Http11AprProtocol

posted @ 2016-06-19 10:31 youngturk 阅读(398) | 评论 (0)编辑 收藏

spring httpInvoke 解决远程调用远程的类的方法

http://zhidao.baidu.com/link?url=6FrnwvBQEZhjM-ooNCuiAra7T6qi9FsFhFvkHBKaOjqovZR86OCsIePi-05nM-fxRrlInEGbElSxlhgO6X7JsaGNdQdNrQ2xE58wglgeQO3 http://blog.csdn.net/liaq325/article/details/8281550 摘自以上 spring httpInvoke

spring httpInvoke 基于spring架构的服务器之间的远程调用实现。通过spring httpInvoke,可以调用远程接口,进行数据交互、业务逻辑操作

服务器端:(被调用一方)

[java] view plain copy
  1. public  class User implements Serializable{//必须实现serializable接口,远程调用的基础  
  2.     private String username;  
  3.     private Date birthday;  
  4.     //构造方法  
  5.     //set get 方法  
  6. }  
  7. public interface UserService{  
  8.     User getUser(String username);  
  9. }  
  10. public UserServiceImpl implements UserService{  
  11.     //实现userService  
  12. }  
重要的配置文件来了。。。。
remote-servlet.xml放在项目根目录下面,跟web.xml相同的级别

暴露给调用端:服务的实现,接口

[html] view plain copy
  1. <bean id="userService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">  
  2.     <property name="service">  
  3.         <bean class="com.cd.Liaq.UserServiceImpl"/>  
  4.     </property>  
  5.     <property name="serviceInterface">  
  6.         <value>com.cd.Liaq.UserService</value>  
  7.     </property>  
  8. </bean>  
暴露了服务的实现和接口,那么怎么访问服务呢?
spring封装访问url

[html] view plain copy
  1. <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">  
  2.     第一种:<property name="urlMap">  
  3.         <map>  
  4.             <entry key="TestUser" value-ref="userService"/>  
  5.         </map>  
  6.     </property>  
  7.     第二种:<prop key="/TestUser">userService</prop>  
  8. </bean>  
web.xml:配置dispatcherServlet共调用一方使用

[html] view plain copy
  1. <!-- spring远程调用 -->  
  2. <servlet>  
  3.     <servlet-name>remote</servlet-name>  
  4.     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  5.     <load-on-startup>1</load-on-startup>  
  6. </servlet>  
  7. <servlet-mapping>  
  8.     <servlet-name>remote</servlet-name>  
  9.     <url-pattern>/remoting/*</url-pattern>  
  10. </servlet-mapping>  
到处为止:被调用端一方完毕!!!!
客户端调用:

[html] view plain copy
  1. <!-- 通过http连接远程系统 -->  
  2. <bean id="memberService"  
  3.     class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">  
  4.     <property name="serviceUrl">  
  5.         <value>http://192.9.200.123:8080/MemberSystem/remoting/memberService</value>  
  6.     </property>  
  7.     <property name="serviceInterface">  
  8.         <value>com.cd.Liaq.UserService</value>  
  9.     </property>  
  10. </bean>  
通过spring容器调用UserService,用到HttpInvokerProxyFactoryBean工厂,配置serviceUrl和serviceInterface
为了提高效率:客户端使用Commons-HttpClient,导入改包,改写配置

[html] view plain copy
  1. <bean id="memberService"  
  2.     class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">  
  3.     <property name="serviceUrl">  
  4.         <value>http://192.9.200.123:8080/MemberSystem/remoting/memberService</value>  
  5.     </property>  
  6.     <property name="serviceInterface">  
  7.         <value>com.cd.Liaq.UserService</value>  
  8.     </property>  
  9.      <property name="httpInvokerRequestExecutor"> //使用指定的执行器执行  
  10.         <ref bean="httpInvokerRequestExecutor" />    
  11.     </property>    
  12. </bean>  
  13. <bean id="httpInvokerRequestExecutor" class="org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor">    
  14.     <property name="httpClient">    
  15.         <bean class="org.apache.commons.httpclient.HttpClient">    
  16.             <property name="connectionTimeout" value="2000" />    
  17.             <property name="timeout" value="5000" />    
  18.         </bean>    
  19.     </property>    
  20. </bean>    

配置超时时间timeout和连接超时connectionTimeout两个属性
优化执行器:多线程===被调用端响应时间缩短很多

[html] view plain copy
  1. <bean id="httpInvokerRequestExecutor" class="org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor">    
  2.     <property name="httpClient">    
  3.         <bean class="org.apache.commons.httpclient.HttpClient">    
  4.             <property name="connectionTimeout" value="2000" />    
  5.             <property name="timeout" value="5000" />    
  6.             <property  name="httpConnectionManager">//控制连接  
  7.                     <ref  bean="multiThreadedHttpConnectionManager" />    
  8.             </property>    
  9.         </bean>    
  10.     </property>    
  11. </bean>    
  12. <bean id="multiThreadedHttpConnectionManager" class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager">    
  13.     <property name="params">    
  14.         <bean class="org.apache.commons.httpclient.params.HttpConnectionManagerParams">    
  15.             <property name="maxTotalConnections"  value="600" />    
  16.             <property name="defaultMaxConnectionsPerHost" value="512" />    
  17.         </bean>    
  18.     </property>    
  19. </bean>    
httpClient的3.1版本不支持这种配置

[html] view plain copy
  1. <property  name="connectionTimeout" value="2000" />      
  2. <property  name="timeout"  value="5000" />    

另外httpClient本身也是多线程的。。HttpClient that uses a default MultiThreadedHttpConnectionManage
<bean class="org.apache.commons.httpclient.params.HttpConnectionManagerParams">  
    <property  name="maxTotalConnections"  value="600" />  
    <property  name="defaultMaxConnectionsPerHost"  value="512" />  
</bean>  
maxConnectionsPerHost 每个主机的最大并行链接数,默认为2 
public static final int DEFAULT_MAX_HOST_CONNECTIONS = 2; 
maxTotalConnections 客户端总并行链接最大数,默认为20  
public static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 20; 

posted @ 2016-06-19 10:29 youngturk 阅读(2250) | 评论 (0)编辑 收藏

6. 分布式缓存集群环境配置 转

     摘要: http://www.cnblogs.com/hoojo/archive/2012/07/19/2599534.htmlhttp://www.cnblogs.com/hellowood23/p/5210267.htmlhttp://blog.csdn.net/ni_hao_ya/article/details/9344779http://www.cnblogs.com/hellowood23/p/...  阅读全文

posted @ 2016-06-19 00:22 youngturk 阅读(173) | 评论 (0)编辑 收藏

手动获取spring的ApplicationContext和bean对象

WEB项目:

方法1:

1
ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc)

 方法2:

1
ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(ServletContext sc)

 方法3:

1
写一个工具类类继承ApplicationObjectSupport,并将这个加入到spring的容器

 方法4:

1
写一个工具类类继承WebApplicationObjectSupport,并将这个加入到spring的容器

 方法5:(推荐)

1
写一个工具类实现ApplicationContextAware接口,并将这个加入到spring的容器

 示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
 
/**
 * 获取ApplicationContext和Object的工具类
 * @author yzl
 *
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public class SpringContextUtils implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
 
    public void setApplicationContext(ApplicationContext arg0)
            throws BeansException {
        applicationContext = arg0;
    }
 
    /**
     * 获取applicationContext对象
     * @return
     */
    public static ApplicationContext getApplicationContext(){
        return applicationContext;
    }
     
    /**
     * 根据bean的id来查找对象
     * @param id
     * @return
     */
    public static Object getBeanById(String id){
        return applicationContext.getBean(id);
    }
     
    /**
     * 根据bean的class来查找对象
     * @param c
     * @return
     */
    public static Object getBeanByClass(Class c){
        return applicationContext.getBean(c);
    }
     
    /**
     * 根据bean的class来查找所有的对象(包括子类)
     * @param c
     * @return
     */
    public static Map getBeansByClass(Class c){
        return applicationContext.getBeansOfType(c);
    }
}

 

 

非WEB项目

1
ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml")

可选的操作方法有:

1
2
3
4
5
6
7
8
9
10
11
一:
String[]   path={"WebRoot/WEB-INF/applicationContext.xml","WebRoot/WEB-INF/applicationContext_task.xml"};
ApplicationContext context = new FileSystemXmlApplicationContext(path);
 
二:
String path="WebRoot/WEB-INF/applicationContext*.xml";
ApplicationContext context = new FileSystemXmlApplicationContext(path);
 
三:
ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:地址");
没有classpath的话就是从当前的工作目录

posted @ 2016-06-18 23:56 youngturk 阅读(245) | 评论 (0)编辑 收藏

Ehcache学习 转

     摘要: http://ligf06.iteye.com/blog/17108875.    在 Spring 中运用 EHCache需要使用 Spring 来实现一个 Cache 简单的解决方案,具体需求如下:使用任意一个现有开源 Cache Framework,要求使用 Cache 系统中 Service 或则 DAO 层的...  阅读全文

posted @ 2016-06-18 15:45 youngturk 阅读(141) | 评论 (0)编辑 收藏

应用技术总结

1.文件上传,ajax引入common,在jsp中进行上传 2.webservice 客户端连接用axis2.jar连接,用axis2的包进行创建 或者用xfx配置发布 3.文件解析,将文件转换成i 4.ftp文件上传下载 5.网上银行农行校验 6.联动用ajax 7.dwrajax 8.邮件发送功能 9.短信发送功能 10.任务定时功能

posted @ 2016-06-18 13:38 youngturk 阅读(152) | 评论 (0)编辑 收藏

java中的缓存技术该如何实现

http://blog.sina.com.cn/s/blog_6aefe42501018wnn.html 1缓存为什么要存在? 2缓存可以存在于什么地方? 3缓存有哪些属性? 4缓存介质? 搞清楚这4个问题,那么我们就可以随意的通过应用的场景来判断使用何种缓存了. 1. 缓存为什么要存在? 一般情况下,一个网站,或者一个应用,它的一般形式是,浏览器请求应用服务器,应用服务器做一堆计算后再请求数据库,数据库收到请求后再作一堆计算后把数据返回给应用服务器,应用服务器再作一堆计算后把数据返回给浏览器.这个是一个标准流程.但是随着互连网的普及,上网的人越来越多,网上的信息量也越来越多,在这两个越来越多的情况下,我们的应用需要支撑的并发量就越来越多.然后我们的应用服务器和数据库服务器所做的计算也越来越多,但是往往我们的应用服务器资源是有限的,数据库每秒中接受请求的次数也是有限的(谁叫俺们的硬盘转速有限呢).如果利用有限的资源来提供尽可能大的吞吐量呢,一个办法:减少计算量,缩短请求流程(减少网络io或者硬盘io),这时候缓存就可以大展手脚了.缓存的基本原理就是打破上图中所描绘的标准流程,在这个标准流程中,任何一个环节都可以被切断.请求可以从缓存里取到数据直接返回.这样不但节省了时间,提高了响应速度,而且也节省了硬件资源.可以让我们有限的硬件资源来服务更多的用户. 2 缓存可以存在于什么地方? Java代码 浏览器---?浏览器和app之间---?分过层的app-?数据库 浏览器---?浏览器和app之间---?分过层的app-?数据库 在上图中,我们可以看到一次请求的一般流程,下面我们重新绘制这张图,让我们的结构稍微复杂一点点. (将app分层) 浏览器---?浏览器和app之间---?分过层的app-?数据库 理论上来将,请求的任何一个环节都是缓存可以作用的地方.第一个环节,浏览器,如果数据存在浏览器上,那么对用户来说速度是最快的,因为这个时候根本无需网络请求.第二个环节,浏览器和app之间,如果缓存加在这个地方,那么缓存对app来说是透明的.而且这个缓存中存放的是完整的页面.第三个节点,app 中本身就有几个层次,那么缓存也可以放在不同的层次上,这一部分是情况或者场景比较复杂的部分.选择缓存时需要谨慎.第四个环节,数据库中也可以有缓存, 比如说mysql的querycache. 那么也就是说在整个请求流程的任何一点,我们都可以加缓存.但是是所有的数据都可以放进缓存的吗.当然不是,需要放进缓存的数据总是有一些特征的,要清楚的判断数据是否可以被缓存,可以被怎样缓存就必须要从数据的变化特征下手. 数据有哪些变化特征?最简单的就是两种,变和不变.我们都知道,不会变化的数据不需要每次都进行计算.问题是难道所有的数据理论上来讲都会变化,变化是世界永恒的主题.也就是说我们把数据分为变和不变两种是不对的,那么就让我们再加一个条件:时间.那么我们就可以把数据特征总结为一段时间内变或者不变.那么根据这个数据特征,我们就可以在合适的位置和合适的缓存类型中缓存该数据. 3缓存有哪些属性 从面向对象的角度来看,缓存就是一个对象,那么是对象,必然有属性.那么下面我们来探讨一下缓存有哪些属性.以下列举我们常用到的3个属性. (1) 命中率 命中率是指请求缓存次数和缓存返回正确结果次数的比例.比例越高,就证明缓存的使用率越高. 命中率问题是缓存中的一个非常重要的问题,我们都希望自己缓存的命中率能达到100%,但是往往事与愿违,而且缓存命中率是衡量缓存有效性的重要指标. (2) 最大元素 缓存中可以存放得最大元素得数量,一旦缓存中元素数量超过这个值,那么将会起用缓存清空策略,根据不同的场景合理的设置最大元素值往往可以一定程度上提高缓存的命中率.从而更有效的时候缓存. (3) 清空策略 1 FIFO ,first in first out ,最先进入缓存得数据在缓存空间不够情况下(超出最大元素限制时)会被首先清理出去 2 LFU , Less Frequently Used ,一直以来最少被使用的元素会被被清理掉。这就要求缓存的元素有一个hit 属性,在缓存空间不够得情况下,hit 值最小的将会被清出缓存。 2 LRU ,Least Recently Used ,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。 4缓存介质 从硬件介质上来将无非就是两种,内存和硬盘(对应应用层的程序来讲不用考虑寄存器等问题).但是往往我们不会从硬件上来划分,一般的划分方法是从技术上划分,可以分成几种,内存,硬盘文件.数据库. (1) 内存.将缓存放在内存中是最快的选择,任何程序直接操作内存都比操作硬盘要快的多,但是如果你的数据要考虑到break down的问题,因为放在内存中的数据我们称之为没有持久话的数据,如果硬盘上没有备份,机器down机之后,很难或者无法恢复. (2) 硬盘.一般来说,很多缓存框架会结合使用内存和硬盘,比如给内存分配的空间有满了之后,会让用户选择把需要退出内存空间的数据持久化到硬盘.当然也选择直接把数据放一份到硬盘(内存中一份,硬盘中一份,down机也不怕).也有其他的缓存是直接把数据放到硬盘上. (3) 数据库.说到数据库,可能有的人会想,之前不是讲到要减少数据库查询的次数,减少数据库计算的压力吗,现在怎么又用数据库作为缓存的介质了呢.这是因为数据库又很多种类型,比如berkleydb,这种db不支持sql语句,没有sql引擎,只是key和value的存储结构,所以速度非常的快,在当代一般的pc上,每秒中十几w次查询都是没有问题的(当然这个是根据业务特征来决定的,如果您访问的数据在分布上是均匀的,那ahuaxuan可不能保证这个速度了). 除了缓存介质之外,ahuaxuan根据缓存和应用的耦合程度将其划分为local cache和remote cache. Local cache是指包含在应用之中的缓存组件.而remote cache指和应用解耦在应用之外的缓存组件.典型的local cache有ehcache,oscache,而remote cache有大名鼎鼎的memcached. Localcache 最大的优点是应用和cache的时候是在同一个进程内部,请求缓存非常快速,完全不需要网络开销等.所以单应用,不需要集群或者集群情况下cache node不需要相互通知的情况下使用local cache比较合适.这也是java中ehcache和oscache这么流行的原因. 但是 Local cache是有一定的缺点的,一般这种缓存框架(比如java中的ehcache或者oscache)都是local cache.也就是跟着应用程序走的,多个应用程序无法直接共享缓存,应用集群的情况下这个问题更加明显,当然也有的缓存组件提供了集群节点相互通知缓存更新的功能,但是由于这个是广播,或者是环路更新,在缓存更新频繁的情况下会导致网络io开销非常大,严重的时候会影响应用的正常运行.而且如果缓存中数据量较大得情况下使用localcache意味着每个应用都有一份这么大得缓存,着绝对是对内存的浪费. 所以这个情况下,往往我们会 选择remote cache,比如memcached.这样集群或者分布式的情况下各个应用都可以共享memcached中的数据,这些应用都通过socket和基于 tcp/ip协议上层的memcached协议直接连接到memcached,有一个app更新了memcached中的值,所有的应用都能拿到最新的值.虽然这个时候多了很多了网络上的开销,但是往往这种方案要比localcache广播或环路更新cache节点要普遍的多,而且性能也比后者高.由于数据只需要保存一份,所以也提高了内存的使用率. 通过以上分析可以看出,不管是local cache,还是remote cache在缓存领域都有自己的一席之地,所以ahuaxuan建议在选择或者使用缓存时一定要根据缓存的特征和我们的业务场景准确判断使用何种缓存.这样才能充分发挥缓存的功能. Ahuaxuan 认为,缓存的使用是架构师的必备技能,好的架构师能够根据数据的类型,业务的场景来准确的判断出使用何种类型的缓存,并且如何使用这种类型的缓存.在缓存的世界里也没有银弹,目前还没有一种缓存可以解决任何的业务场景或者数据类型,如果这种技术出现了,那架构师就又更不值钱了.呵呵. OSCache      OSCache是个一个广泛采用的高性能的J2EE缓存框架,OSCache能用于任何Java应用程序的普通的缓存解决方案。      OSCache有以下特点:      缓存任何对象,你可以不受限制的缓存部分jsp页面或HTTP请求,任何java对象都可以缓存。      拥有全面的API--OSCache API给你全面的程序来控制所有的OSCache特性。      永久缓存--缓存能随意的写入硬盘,因此允许昂贵的创建(expensive-to-create)数据来保持缓存,甚至能让应用重启。      支持集群--集群缓存数据能被单个的进行参数配置,不需要修改代码。      缓存记录的过期--你可以有最大限度的控制缓存对象的过期,包括可插入式的刷新策略(如果默认性能不需要时)。      官方网站 http://www.opensymphony.com/oscache/      Java Caching System      JSC(Java Caching System)是一个用分布式的缓存系统,是基于服务器的java应用程序。它是通过提供管理各种动态缓存数据来加速动态web应用。      JCS和其他缓存系统一样,也是一个用于高速读取,低速写入的应用程序。      动态内容和报表系统能够获得更好的性能。      如果一个网站,有重复的网站结构,使用间歇性更新方式的数据库(而不是连续不断的更新数据库),被重复搜索出相同结果的,就能够通过执行缓存方式改进其性能和伸缩性。      官方网站 http://jakarta.apache.org/turbine/jcs/      EHCache      EHCache 是一个纯java的在进程中的缓存,它具有以下特性:快速,简单,为Hibernate2.1充当可插入的缓存,最小的依赖性,全面的文档和测试。      官方网站 http://ehcache.sourceforge.net/      JCache      JCache是个开源程序,正在努力成为JSR-107开源规范,JSR-107规范已经很多年没改变了。这个版本仍然是构建在最初的功能定义上。      官方网站 http://jcache.sourceforge.net/      ShiftOne      ShiftOne Java Object Cache是一个执行一系列严格的对象缓存策略的Java lib,就像一个轻量级的配置缓存工作状态的框架。      官方网站 http://jocache.sourceforge.net/      SwarmCache      SwarmCache是一个简单且有效的分布式缓存,它使用IP multicast与同一个局域网的其他主机进行通讯,是特别为集群和数据驱动web应用程序而设计的。SwarmCache能够让典型的读操作大大超过写操作的这类应用提供更好的性能支持。      SwarmCache使用JavaGroups来管理从属关系和分布式缓存的通讯。      官方网站 http://swarmcache.sourceforge.net      TreeCache / JBossCache      JBossCache是一个复制的事务处理缓存,它允许你缓存企业级应用数据来更好的改善性能。缓存数据被自动复制,让你轻松进行JBoss服务器之间的集群工作。JBossCache能够通过JBoss应用服务或其他J2EE容器来运行一个MBean服务,当然,它也能独立运行。      JBossCache包括两个模块:TreeCache和TreeCacheAOP。      TreeCache --是一个树形结构复制的事务处理缓存。      TreeCacheAOP --是一个“面向对象”缓存,它使用AOP来动态管理POJO(Plain Old Java Objects)      注:AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向方面编程。      官方网站 http://www.jboss.org/products/jbosscache      WhirlyCache      Whirlycache是一个快速的、可配置的、存在于内存中的对象的缓存。它能够通过缓存对象来加快网站或应用程序的速度,否则就必须通过查询数据库或其他代价较高的处理程序来建立。

posted @ 2016-06-18 12:29 youngturk 阅读(185) | 评论 (0)编辑 收藏

Spring为什么先定义接口

首先你要理解OOP的思想,是面向接口编程.
什么叫面向接口编程呢?
假如你买了一个多媒体设备,它给了你一个遥控,你想要知道的只是按什么按钮,它会播放什么
而遥控里面是怎样运行,还有屏幕里面怎么工作,你想知道吗?
你完全不会去想了解.
那如果多媒体设备需要更新,比如优化内部运行效率,
但是优化完了,遥控的按钮不变,设备的所有操作方式都不变,按这个按钮还是显示相同的东西
那内部怎么变化你完全不需要在意.

这就是面向接口编程.
无论类的内部怎么实现,它对外的接口不变,那它的使用方式就不会变
假设Main类要使用D类的一个draw的方法,
方法名叫 draw():void
不管draw里面是怎样的,Main类里就是这样用,
那么你就从这个接口出发,里面怎么实现是D类的事了,Main类只关心怎么用而已.
其他类要使用它,还是相同
这就大大减少了维护的成本.
因为如果D类出问题,Main类是完全不用改变的.

从上观察,公开的接口越多,维护成本就越大.
维护就越麻烦.所以我们先写接口,定死了公开的接口,
那维护就很方便,出错也只是一个类的事,而不用同时修改多个协同类

posted @ 2016-06-16 16:40 youngturk 阅读(185) | 评论 (0)编辑 收藏

一、Spring单例模式与线程安全

http://www.cnblogs.com/doit8791/p/4093808.html
Spring框架里的bean,或者说组件,获取实例的时候都是默认的单例模式,这是在多线程开发的时候要尤其注意的地方。

 http://www.cnblogs.com/hoojo/archive/2011/05/05/2038101.html

单例模式的意思就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。
当多用户同时请求一个服务时,容器会给每一个请求分配一个线程,这是多个线程会并发执行该请求多对应的业务逻辑(成员方法),此时就要注意了,如果该处理逻辑中有对该单列状态的修改(体现为该单列的成员属性),则必须考虑线程同步问题
同步机制的比较  ThreadLocal和线程同步机制相比有什么优势呢?ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。 
  在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。 
  而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。 
  由于ThreadLocal中可以持有任何类型的对象,低版本JDK所提供的get()返回的是Object对象,需要强制类型转换。但JDK 5.0通过泛型很好的解决了这个问题,在一定程度地简化ThreadLocal的使用
 概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。 
  Spring使用ThreadLocal解决线程安全问题 
  我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态采用ThreadLocal进行处理,让它们也成为线程安全的状态,因为有状态的Bean就可以在多线程中共享了。 
  一般的Web应用划分为展现层、服务层和持久层三个层次,在不同的层中编写对应的逻辑,下层通过接口向上层开放功能调用。在一般情况下,从接收请求到返回响应所经过的所有程序调用都同属于一个线程
ThreadLocal是解决线程安全问题一个很好的思路,它通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题。在很多情况下,ThreadLocal比直接使用synchronized同步机制解决线程安全问题更简单,更方便,且结果程序拥有更高的并发性。 
如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。 或者说:一个类或者程序所提供的接口对于线程来说是原子操作或者多个线程之间的切换不会导致该接口的执行结果存在二义性,也就是说我们不用考虑同步的问题。  线程安全问题都是由全局变量及静态变量引起的。  
若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。
1) 常量始终是线程安全的,因为只存在读操作。 
2)每次调用方法前都新建一个实例是线程安全的,因为不会访问共享的资源。
3)局部变量是线程安全的。因为每执行一个方法,都会在独立的空间创建局部变量,它不是共享的资源。局部变量包括方法的参数变量和方法内变量。
有状态就是有数据存储功能。有状态对象(Stateful Bean),就是有实例变量的对象  ,可以保存数据,是非线程安全的。在不同方法调用间不保留任何状态。
无状态就是一次操作,不能保存数据。无状态对象(Stateless Bean),就是没有实例变量的对象  .不能保存数据,是不变类,是线程安全的。
有状态对象:
无状态的Bean适合用不变模式,技术就是单例模式,这样可以共享实例,提高性能有状态的Bean,多线程环境下不安全,那么适合用Prototype原型模式。Prototype: 每次对bean的请求都会创建一个新的bean实例。
Struts2默认的实现是Prototype模式。也就是每个请求都新生成一个Action实例,所以不存在线程安全问题。需要注意的是,如果由Spring管理action的生命周期, scope要配成prototype作用域。

 

二、线程安全案例:

SimpleDateFormat(下面简称sdf)类内部有一个Calendar对象引用,它用来储存和这个sdf相关的日期信息,例如sdf.parse(dateStr), sdf.format(date) 诸如此类的方法参数传入的日期相关String, Date等等, 都是交友Calendar引用来储存的.这样就会导致一个问题,如果你的sdf是个static的, 那么多个thread 之间就会共享这个sdf, 同时也是共享这个Calendar引用, 并且, 观察 sdf.parse() 方法,你会发现有如下的调用:
Date parse() {
  calendar.clear(); // 清理calendar
  ... // 执行一些操作, 设置 calendar 的日期什么的
  calendar.getTime(); // 获取calendar的时间
}
这里会导致的问题就是, 如果 线程A 调用了 sdf.parse(), 并且进行了 calendar.clear()后还未执行calendar.getTime()的时候,线程B又调用了sdf.parse(), 这时候线程B也执行了sdf.clear()方法, 这样就导致线程A的的calendar数据被清空了(实际上A,B的同时被清空了). 又或者当 A 执行了calendar.clear() 后被挂起, 这时候B 开始调用sdf.parse()并顺利i结束, 这样 A 的 calendar内存储的的date 变成了后来B设置的calendar的date
这个问题背后隐藏着一个更为重要的问题--无状态:无状态方法的好处之一,就是它在各种环境下,都可以安全的调用。衡量一个方法是否是有状态的,就看它是否改动了其它的东西,比如全局变量,比如实例的字段。format方法在运行过程中改动了SimpleDateFormat的calendar字段,所以,它是有状态的。
  这也同时提醒我们在开发和设计系统的时候注意下一下三点:
  1.自己写公用类的时候,要对多线程调用情况下的后果在注释里进行明确说明
  2.对线程环境下,对每一个共享的可变变量都要注意其线程安全性
  3.我们的类和方法在做设计的时候,要尽量设计成无状态的
 三.解决办法
  1.需要的时候创建新实例:
  说明:在需要用到SimpleDateFormat 的地方新建一个实例,不管什么时候,将有线程安全问题的对象由共享变为局部私有都能避免多线程问题,不过也加重了创建对象的负担。在一般情况下,这样其实对性能影响比不是很明显的。
  2.使用同步:同步SimpleDateFormat对象
public class DateSyncUtil {
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      
    public static String formatDate(Date date)throws ParseException{
        synchronized(sdf){
            return sdf.format(date);
        }  
    }
    
    public static Date parse(String strDate) throws ParseException{
        synchronized(sdf){
            return sdf.parse(strDate);
        }
    } 
}
  说明:当线程较多时,当一个线程调用该方法时,其他想要调用此方法的线程就要block,多线程并发量大的时候会对性能有一定的影响。
  3.使用ThreadLocal: 
public class ConcurrentDateUtil {
    private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
    };
    public static Date parse(String dateStr) throws ParseException {
        return threadLocal.get().parse(dateStr);
    }
    public static String format(Date date) {
        return threadLocal.get().format(date);
    }
}
public class ThreadLocalDateUtil {
    private static final String date_format = "yyyy-MM-dd HH:mm:ss";
    private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>(); 
 
    public static DateFormat getDateFormat()   
    {  
        DateFormat df = threadLocal.get();  
        if(df==null){  
            df = new SimpleDateFormat(date_format);  
            threadLocal.set(df);  
        }  
        return df;  
    }  
    public static String formatDate(Date date) throws ParseException {
        return getDateFormat().format(date);
    }
    public static Date parse(String strDate) throws ParseException {
        return getDateFormat().parse(strDate);
    }   
}
  说明:使用ThreadLocal, 也是将共享变量变为独享,线程独享肯定能比方法独享在并发环境中能减少不少创建对象的开销。如果对性能要求比较高的情况下,一般推荐使用这种方法。
  4.抛弃JDK,使用其他类库中的时间格式化类:
  1.使用Apache commons 里的FastDateFormat,宣称是既快又线程安全的SimpleDateFormat, 可惜它只能对日期进行format, 不能对日期串进行解析。
  2.使用Joda-Time类库来处理时间相关问题
  做一个简单的压力测试,方法一最慢,方法三最快,但是就算是最慢的方法一性能也不差,一般系统方法一和方法二就可以满足,所以说在这个点很难成为你系统的瓶颈所在。从简单的角度来说,建议使用方法一或者方法二,如果在必要的时候,追求那么一点性能提升的话,可以考虑用方法三,用ThreadLocal做缓存。
  Joda-Time类库对时间处理方式比较完美,建议使用。

posted @ 2016-06-16 14:48 youngturk 阅读(230) | 评论 (0)编辑 收藏

过滤器(filter)和拦截器(interceptor)区别

一、filter基于filter接口中的doFilter回调函数,interceptor则基于Java本身的反射机制; 二、filter是依赖于servlet容器的,没有servlet容器就无法回调doFilter方法,而interceptor与servlet无关; 三、filter的过滤范围比interceptor大,filter除了过滤请求外通过通配符可以保护页面、图片、文件等,而interceptor只能过滤请求,只对action起作用,在action之前开始,在action完成后结束(如被拦截,不执行action); 四、filter的过滤一般在加载的时候在init方法声明,而interceptor可以通过在xml声明是guest请求还是user请求来辨别是否过滤; 五、interceptor可以访问action上下文、值栈里的对象,而filter不能; 六、在action的生命周期中,拦截器可以被多次调用,而过滤器只能在容器初始化时被调用一次

posted @ 2016-06-15 22:28 youngturk 阅读(392) | 评论 (0)编辑 收藏

web.xml的 servlet里面配置log4j

loginit com.cenin.util.servlet.LogInit log4jConfig /WEB-INF/classes/log4j.properties 1

posted @ 2016-06-15 22:22 youngturk 阅读(157) | 评论 (0)编辑 收藏

String 自带邮件发送功能

mail.mymail.cn webmaster password true

posted @ 2016-06-15 22:12 youngturk 阅读(154) | 评论 (0)编辑 收藏

Spring 的天气预报定时功能

!-- 天气预报的定时器 TianQiUtilTask 继承TimerTask,实现run功能--> 1000 3600

posted @ 2016-06-15 21:59 youngturk 阅读(113) | 评论 (0)编辑 收藏

多线程,定时任务

http://www.cnblogs.com/hoojo/archive/2011/05/05/2038101.html

package comz.autoupdatefile;

import java.util.Timer;
import java.util.TimerTask;

public class M {
 public static void main(String[] args) {
  // TODO todo.generated by zoer
  Timer timer = new Timer();
  timer.schedule(new MyTask(), 1000, 2000);
 }
}

class MyTask extends TimerTask {

 @Override
 public void run() {
  System.out.println("dddd");

 }

}


这样,就可以在1秒钟之后开始执行mytask,每两秒钟执行一次。

当然,timer的功能也可以通过自己构造线程,然后在线程中用sleep来模拟停止一段时间,然后再执行某个动作。

其实,看一下timertask的源码就立即可以知道,timertask就是实现了runnable接口的。也就是说,通过timer来间隔一段时间执行一个操作,也是通过一个线程来做到的。

posted @ 2016-06-15 15:33 youngturk 阅读(269) | 评论 (0)编辑 收藏

oracle只导出数据的方法

 1、EXP: 
      有三种主要的方式(完全、用户、表) 
      1、完全: 
          EXP SYSTEM/MANAGER BUFFER=64000 FILE=C:\FULL.DMP FULL=Y 
          如果要执行完全导出,必须具有特殊的权限 
      2、用户模式: 
          EXP SONIC/SONIC    BUFFER=64000 FILE=C:\SONIC.DMP OWNER=SONIC 
          这样用户SONIC的所有对象被输出到文件中。 
      3、表模式:
          EXP SONIC/SONIC    BUFFER=64000 FILE=C:\SONIC.DMP OWNER=SONIC TABLES=(SONIC) 
          这样用户SONIC的表SONIC就被导出 

posted @ 2015-07-17 14:17 youngturk 阅读(332) | 评论 (0)编辑 收藏

Oracle11g R2用EXP导出时报EXP-00011错误的解决方法 (转)

用定时器 + bat脚本做oracle的备份,已经备份了几个月了。这几天突然发现备份出来的dmp数据完全没法重新导入到新的数据库中。 起初以为是版本问题,或者导出参数的问题,于是在网上不停的搜索、尝试,最后还是没发现问题原因。 算了还是研究一下导入日志中的错误,于是将日志中出错误的表尝试单独导出,居然出现EXP-00011::表不存在 错误,可是数据库中明明有这个表呀。根据这个方向再上网一查,终于找到原因了,原来在11g中空表是默认是不占Segment的,导致备份导出的时候压根就没导出那些空表,这样才出现备份的dmp没法导入的问题,敢情我几个月的备份工作都白做了。 可ORACLE 你妈X的,备份导出时没导出空表这么大的事情你居然没有任何提示,你他*妈的是为了创造客服赚钱的机会么? 哎,处理过程如下: 1.用system帐号进入: 1.1 查看是否为true show parameter deferred_segment_creation; 1.2 修改为false alter system set deferred_segment_creation=false; 2.用数据库帐号登录: 2.1 查找所有数据表为空的表 select table_name from user_tables where NUM_ROWS=0; 2.2 把这些表组成修改Segment的脚本: select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0; 2.3 将2.2中查询的结果导出来,或者复制出来,并执行修改所有空表。 这个时候就能把所有空表导出来了。 感谢以下两位的帖子,给了我很大帮助 http://arthas-fang.iteye.com/blog/875258 http://wanwentao.blog.51cto.com/2406488/545154

posted @ 2014-10-24 10:40 youngturk 阅读(481) | 评论 (0)编辑 收藏

linux window共用方法路径分割

regex为\\\\,因为在java中\\表示一个\,而regex中\\也表示\,所以当\\\\解析成regex的时候为\\。 由于unix中file.separator为斜杠"/",下面这段代码可以处理windows和unix下的所有情况: String temp[] = name.replaceAll("\\\\","/").split("/"); if (temp.length > 1) { name = temp[temp.length - 1]; }

posted @ 2014-08-14 14:43 youngturk 阅读(243) | 评论 (0)编辑 收藏

<2014年8月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456

导航

统计

公告

this year :
1 jQuery
2 freemarker
3 框架结构
4 口语英语

常用链接

留言簿(6)

随笔分类

随笔档案

文章分类

文章档案

相册

EJB学习

Flex学习

learn English

oracle

spring MVC web service

SQL

Struts

生活保健

解析文件

搜索

最新评论

阅读排行榜

评论排行榜