Fork me on GitHub
我们到底能走多远系列

我们到底能走多远系列

当你想在web应用中使用线程的时候-我们到底能走多远系列(24)

先不扯淡,先推荐:

  如果你热爱英文技术原文的话,这个推荐的网站绝对让你会想抱一抱他:http://www.salttiger.com/(也许你早就知道啦) 再一次感谢那些乐于分享和贡献的勇士们,虽然互联网上我们互不相识,却通过知识,我们建立了某种超越空间时光的特殊关系,想想,这真的很有趣。

扯淡:

  最*朋友在老家工作量一年,又跑来城市奋斗。可是纳闷的是我数来数去,当时留在城市的人数正在逐年的下降,可这货怎么还会来呢?

最*,想比较深入的学习事务,可是看了好多文章,却越看越糊涂,有想起去看别的东西,有点三心两意的感觉了。真心希望有人带一下,轻松一点,唉。神,赐我一个大牛吧!

现在的公司,虽然是国内的,工作管理上较为开放,很多事可以自己决定,有时候自己会准备好几个方案,和同事讨论一下,选个比较优的,再去写代码,到也不错。

 

主题:

  初入web的时候,我们总是会被教育,web应用无需关心线程的问题,学好基本的框架,就可以上手啦。

  其实实际项目中使用多线程的情况是很正常的,在业务复杂的应用程序中,比如如果一个业务非常耗时,我们只好采用异步的方式,避免影响web端的展示,再有定时监控数据库字段的变化的业务,或者是batch处理(半夜处理数据库.....)也就是定时任务啦等等。

我就把最*遇到的问题展现给各位,希望大家能给点好的意见,我都会尝试使用,并应用到项目中去。

1,发邮件问题

  项目中,注册完毕后,需要向用户的邮箱发送邮件,开始的代码就是把发邮件的逻辑封装在service层,然后action层调用完毕后,返回页面,展现页面。实际测试还没有发现页面跳转太慢的情况,但是为了安全起见,还有一个原则就是我们不要把一些会抛诸runtimeException的逻辑放在和展现页面的逻辑一起,异步是唯一的选择。

多线程的实现是利用spring的框架:

线程池bean配置:

      <bean id="mailTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <property name="corePoolSize" value="3"/>
        <property name="maxPoolSize" value="10"/>
    </bean>

直接把mailTaskExecutor注入进service层,就可以使用啦!

一下是发送邮件的简单代码:

复制代码
    public boolean sendMail4D(String email,String basePath, String cstmName,String userName,String passWord) {
        final MailSenderInfo mailInfo = getMailInfo(email);
        final Map model = new HashMap();
        model.put("basePath", basePath);
        model.put("cstmName", cstmName);
        model.put("username", userName);
        model.put("password", passWord);
        model.put("dealerLogin", dealerLogin);
        model.put("customerTel", customerTel);
        model.put("cusEmailAddress", cusEmailAddress);
        mailTaskExecutor.execute(new Runnable(){
               public void run(){
                   String result;
                try {
                    result = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine,
                                                                "dealer-reg-send-mail.vm", model);
                    mailInfo.setContent(result);
                    SimpleMailSender sms = new SimpleMailSender();
                    sms.sendHtmlMail(mailInfo);// 发送文体格式
                } catch (Exception e) {
                    log.error("send mail failed,there has a Exception");
                    log.error(e.toString());
                    e.printStackTrace();
                }

               }
        });
        return true;
    }
复制代码

  这样以来,在action层调用这个方法后就不用等待,邮件发送完毕后的返回了,唯一的坏处是,我们不知道邮件是否发送成功,这可能需要更多其他的代码来弥补了。

 

2,数据库字段监控问题

问题描述:

比如我们进行一个发布评论的操作,发布这个过程是通过webservice来调用另一个系统来实现的,在调用前我们把这个数据的字段置为发布中,对方回调成功后就置为发布成功,失败就是发布失败,但是有一种情况那就是对方出现异常,回调没来调,这样会导致这条数据一直为发布中... 这样的数据就需要我这边来判断,然后把它置为发布失败!

开始的想法:

每次调用对方的发布接口时,都启用一个线程,这个线程每隔一分钟检查数据库中这条数据的标志位,检查三次,如果始终是发布中,就把它置为发布失败

ok,开始去实现了,想到前面提到的spring框架提供的线程池,也不是很难了吧。

一下是线程的代码示例:(spring的线程配置与前面差不多)

复制代码
import org.apache.log4j.Logger;

import com.syezon.webapp.constant.BusinessConstants;
import com.syezon.webapp.dao.ReleaseDao;
import com.syezon.webapp.model.Release;

public class CheckAdvStatusThread extends Thread{
    
    public static Logger log = Logger.getLogger(CheckAdvStatusThread.class);
    private ReleaseDao releaseDao;
    private Long releaseId;
    
    public CheckAdvStatusThread(Long releaseId, ReleaseDao releaseDao){
        this.releaseId = releaseId;
        this.releaseDao = releaseDao;
    }

    public void setReleaseDao(ReleaseDao releaseDao) {
        this.releaseDao = releaseDao;
    }

    public void run() {
        
        int i = 0;
        for ( ; i < 3; i++) {
            try {
                // 半分钟
                Thread.sleep(30000);
                
                Release release = releaseDao.getById(releaseId);
                if(release.getStatus() == BusinessConstants.RELEASE_STATUS_PUBING){
                    continue;
                }else{
                    break;
                }
            } catch (InterruptedException e) {
                log.error("there has a InterruptedException");
                e.printStackTrace();
            }
        }
        // 一分半钟
        if(i == 3){
            releaseDao.setStatus(releaseId, BusinessConstants.RELEASE_STATUS_PUB_FAIL);
        }
    }

}
复制代码

代码也没什么好解释了,特别要注意的是:构造方法,dao层的bean是通过构造时进来的,为什么不利用spring注入呢?事实上,试过的朋友应该多知道,在线程类中是无法注入的,可能线程启动的方式绕过了一个正常实例产生时需要的流程吧,解决方法有:

复制代码
在用多线程的时候,里面要用到Spring注入服务层,或者是逻辑层的时候,一般是注入不进去的。具体原因应该是线程启动时没有用到Spring实例不池。所以注入的变量值都为null。

如果在run方法里面加载application.xml,来取得bean时,由于重复加载,一般情况下会耗尽内存,抛出内存溢出错误。所以这的确是一个很头痛的问题。

有一个方法可以解决注不进去的问题。就是在声明变量的时候,前面加static。这样在初始化的时候它就会加载application.xml,得到bean。

关于这个问题的根本机制没有作深入的研究,好在问题解决了。

从这个例子体会到林信良说过的,没有一个技术是完美的,不要为了Spring而Spring。不要为了注入而注入。
复制代码

我没有使用以上方式是因为,我尝试了一下,不可行啊,但是我网上寻找的答案太过一直,所以我认为我是个特例,如果你也遇到类似的问题,大可以先尝试一下上面的方法。

 

以上方法的问题:并发量大的时候会导致大量线程的启用和销毁,在3分钟的时间里,真的难以想象不断创建线程会发生什么,想想也有点怕怕啊!

亲,如果是你,你怕吗?

 

下班前的指导:

上级给出的意见是这样,采用一个队列(说白了,不就是LinkList嘛),然后启动一个线程,这个线程对着个队列进行检测。每次发布的时候向这个队列里塞信息,线程根据队列中的信息,判断发布中的状态是否维持到了超时的范围,就把它置为发布失败,队列删除这信息

上面的想法,其实很不错,如此解决了第一种方式带来的大部分问题。

回去想了好久,我想问一下你们,你们有类似的经验吗,给点提示,例子什么的啊~~

 

经过和同事的沟通,对方建议采用定时器更加靠谱!

目前,使用的是定时器方式解决的:

spring也支持定时器嘛,配置如下:

复制代码
      <!-- 需要执行的任务 -->
    <bean id="checkAdvStatusJob" class="org.springframework.scheduling.quartz.JobDetailBean">
        <property name="jobClass" value="com.syezon.webapp.util.CheckAdvStatusMonitor"/>
        <property name="jobDataAsMap">   
        <map>
            <entry key="releaseDao">
                <ref bean="releaseDao"/>
            </entry>
        </map>  
    </property>
    </bean>
    <!-- 对任务的参数的设置 -->
    <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
        <property name="jobDetail" ref="checkAdvStatusJob" />
        <property name="startDelay" value="180000" /><!--启动3分钟后再开始-->
        <property name="repeatInterval" value="180000" /><!--每3分钟跑一次-->
    </bean>
    <!-- 启动任务 -->
    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <!--<property name="triggers" ref="cronTrigger" />-->
        <property name="triggers" ref="simpleTrigger" />
    </bean>
    
复制代码

  注意checkAdvStatusJob的配置,正真的逻辑我们是写在jobClass里的。注入到jobClass的dao层bean只能通过上面的方式实现,不能用普通spring的property 去实现哦!releaseDao是注入到jobClass里的!下面的配置就不解释啦。

 

CheckAdvStatusMonitor类,简单的示例:
复制代码
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

import com.syezon.webapp.constant.BusinessConstants;
import com.syezon.webapp.dao.ReleaseDao;
import com.syezon.webapp.model.Release;

public class CheckAdvStatusMonitor extends QuartzJobBean{
    public static Logger log = Logger.getLogger(CheckAdvStatusMonitor.class);
    private ReleaseDao releaseDao;
    
    @Override
    protected void executeInternal(JobExecutionContext arg0)
            throws JobExecutionException {
        
        log.info("CheckAdvStatusMonitor begin");
        
        // 查询全部发布中状态的发布信息
        List<Release> releases = releaseDao.getByStatus(BusinessConstants.RELEASE_STATUS_PUBING);
        if(releases == null || releases.size() <= 0){
            log.info("CheckAdvStatusMonitor end - there has no publishing release");
            return;
        }
        for (Release release : releases) {
            Date createDate = release.getReleaseTime();
            Date currentDate = new Date();
            long l = currentDate.getTime() - createDate.getTime();
            // 超过三分钟
            if(l > 180000){
                log.info("CheckAdvStatusMonitor change a status");
                releaseDao.setStatus(release.getId(), BusinessConstants.RELEASE_STATUS_PUB_FAIL);
                log.info("CheckAdvStatusMonitor change a status, releaseId = release.getId()");
            }
        }
        log.info("CheckAdvStatusMonitor end");
    }

    public void setReleaseDao(ReleaseDao releaseDao) {
        this.releaseDao = releaseDao;
    }

}
复制代码

 

好了,事情描述完啦,亲,你有没有好的建议? 

 

 

 

让我们继续前行

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

努力不一定成功,但不努力肯定不会成功。
共勉。

 

 

 
 
分类: Java

Java

当你想在web应用中使用线程的时候-我们到底能走多远系列(24)
摘要: 我们到底能走多远系列(24)先不扯淡,先推荐: 如果你热爱英文技术原文的话,这个推荐的网站绝对让你会想抱一抱他:http://www.salttiger.com/ (也许你早就知道啦) 再一次感谢那些乐于分享和贡献的勇士们,虽然互联网上我们互不相识,却通过知识,我们建立了某种超越空间时光的特殊关系,想想,这真的很有趣。扯淡: 最*朋友在老家工作量一年,又跑来城市奋斗。可是纳闷的是我数来数去,当时留在城市的人数正在逐年的下降,可这货怎么还会来呢?最*,想比较深入的学习事务,可是看了好多文章,却越看越糊涂,有想起去看别的东西,有点三心两意的感觉了。真心希望有人带一下,轻松一点,唉。神,赐我一个..阅读全文

posted @ 2013-03-18 22:03 每当变幻时 阅读(63) | 评论 (0) 编辑

文件上传+截图+预览升级版-我们到底能走多远系列(23)
摘要: 我们到底能走多远系列(23)扯淡:新的一年开始啦,各位有志青年也该发力学习,工作,赚钱啦! 来个笑话:劫匪进某银行抢劫:钱是国家的,命是自己的!通通不许动!” 于是没有一个人动。抢劫成功。 一个新来硕士劫匪问老大:我们赶快数一下抢了多少吧。老劫匪说,你傻啊?这么多数到什么时候啊?今天晚上看新闻不就知道了吗?(各位这就是工作经验啊) 第二天劫匪们看新闻:4名劫匪,劫去某银行,1个亿... 老大开骂了:不对啊,昨天数了3边就1千万呀,马德~,这么幸苦,人家动一下嘴皮子就赚了我们9倍。再也不干抢银行了~(这就是程序员啊) 主题:1,截图改进年前写的,上传图片,截图:抓我 供大家参考,上次的...阅读全文

posted @ 2013-03-04 17:08 每当变幻时 阅读(1742) | 评论 (4) 编辑

文件下载-excel导出-我们到底能走多远系列(22)
摘要: 我们到底能走多远系列(22)扯淡:老规矩,先扯淡,老实说,过年就是回家在亲戚面前吹吹牛喝喝酒,再听听别人的牛,然后回来继续苦逼.... 所以不是你把别人吹倒,就是别人把你吹倒,大家要加油吹哦!-----------------------------------------最*很多人纠结自己文章被别人抄袭的事。我一直想不明白:自己写的博客被人抄袭,甚至当成别人的原创这种情况对自己有多大的伤害?我不明白:除了自己虚荣心上的一点挫折,其他损失还有多少呢?除了部分恶意的抄袭行为,的确要反对外。我觉得:一个分享的行为,被放大,被传播,本来就是一件很nice,很cool的事。我个人也会转文章,一般...阅读全文

posted @ 2013-02-04 19:37 每当变幻时 阅读(1820) | 评论 (7) 编辑

图片尺寸判断等-我们到底能走多远系列(21)
摘要: 我们到底能走多远系列(21)扯淡:又是一年过年,给各位拜个很早很早的年,实在点的祝福:祝各位明年工资全部翻一番啦!主题:1,判断上传图片尺寸功能如下代码即可在页面上结果掉这个问题:var iconElement = $("#photo");var image = new Image();image.src = iconElement.attr("src");var realWidth = image.width;var realHeight = image.height;但是因为我后续代码中使用了截图的插件,导致插件无法正常使用。被迫本人改变了流程:点击阅读全文

posted @ 2013-01-29 13:09 每当变幻时 阅读(1021) | 评论 (2) 编辑

图片上传+预览+剪切解决方案-我们到底能走多远系列(20)
摘要: 我们到底能走多远系列(20)扯淡:12月15号预订的mx2,现在还没货,唉悲剧。本来想参加朋友婚礼前换个手机的,看来是指望不上了,朋友结婚,5星级酒店,那酒店我高中的时候每天会望望它的楼顶有没有盘旋的直升机,总算咋也能进去吃个饭喝个酒啦,咋农民也就这么点追求,哈哈。主题:图片上传,预览,剪切在很多网站上都会使用,可是到自己真正想做的时候,却遇到了各种困难很问题,总算也是完整方案出来啦。分享一下。表现流程如下:步骤1:点击浏览按钮选中图片-------1------>onchange事件把图片上传到服务器-------2----->图片路径回传步骤2:进入切割图片------3---阅读全文

posted @ 2013-01-16 12:47 每当变幻时 阅读(4292) | 评论 (28) 编辑

web应用图片存取体验-我们到底能走多远系列(19)
摘要: 我们到底能走多远系列(19)扯淡: 连续加班,效率急剧下降中.....遇到存图片的问题,解决方案很多,时间太紧,从简单方式开始学习吧。1,把图片存到数据库里,用的时候把它取出来。取出来有有个选择是需要一个零时文件来存,用路径在页面显示,这样问题比较多,不建议使用。另一种方式就是直接把取出来的二进制文件传给页面,如下结合ibatis实现:bean代码:注意:license字段和identityCard字段是byte[],在数据库中我们采用clob来定义(orcale数据库)。View Code public class Dealer extends User { /** * ...阅读全文

posted @ 2013-01-11 09:14 每当变幻时 阅读(1671) | 评论 (6) 编辑

ibatis 一对多 解决方案
摘要: sqlMap文件中的resultMap: <resultMap id="productAndPackageResult" class="productAndPackage" > <result column="ID" property="id" jdbcType="DECIMAL" /> <result column="NAME" property="name" jdbcType="VARCHAR" /&g阅读全文

posted @ 2013-01-04 21:54 每当变幻时 阅读(198) | 评论 (0) 编辑

关于spring和ibatis的整合
摘要: 没大段时间写博客,工作的时候记录一些,等有时间了再写博客总结吧。现在都是加班来会议一天到底学到了什么,然后记录一些... 觉得盲目的工作实在是太无趣了。spring现在普及度很广,在项目中就像千手观音一般,无所不能。而ibatis几十年来的orm,现已经转成myBitis,鉴于现在orm的数目是在太多,ibatis也越来越少人用了,事实上一个orm在spring看来只是千手观音中的一个手上的法宝罢了。applicationContext.xml<?xml version="1.0" encoding="UTF-8"?><beans xm阅读全文

posted @ 2012-12-25 00:12 每当变幻时 阅读(278) | 评论 (0) 编辑

Java NIO深入(Buffer)-我们到底能走多远系列(18)
摘要: 我们到底能走多远系列(18)扯淡:最*想要跳槽,现公司的主管不高兴,没提的时候关系好像很好,提的时候我比较坚决,他硬要我留一个月,老实说我想弄个三周就好了,对,国际惯例一个月,我也是想砍个一周下来休息下,他居然恐吓我,表达出我不仁他就不义的态度,表示可以再没走的时候为难我。现在开始挑我工作毛病了,态度已经不行了,有点装不住了,哈哈。我想,你这么搞我,我交接也不会尽全力了的,做到本职就滚蛋,留下的坑,你们慢慢填。 最*一个月,经历了些事情,又教育了我一边,要投资自己,让自己变强,才能在有风雨时不倒。侥幸想在别人的树下躲避风雨的,今天可能过了关,包不好明天能不能过。我觉得,不要受制于人的要求是有.阅读全文

posted @ 2012-12-03 22:07 每当变幻时 阅读(1117) | 评论 (4) 编辑

Java NIO基础 -我们到底能走多远系列(17)
摘要: 我们到底能走多远系列(17)扯淡: 长期接触所谓web框架的企业级应用的开发者们,不知道你们有没有这样的感受,几年之后,发现:路越走越窄,学的东西大多是表层的,编程的技巧没有太大的改变,接触大量的所谓框架也写不出一个核心的模块,学习了框架的原理后也不会很好的设计,大量调用别人的库函数感觉看得懂业务的人都可以写。 我觉得作为从事编码行业的我们,埋头苦干是必备的素质,但是抬头思考却是核心的竞争力,因为前者是进步的一个条件,而后者则是进步的原动力。 这里我斗胆提出一个自己想法:假如你没有进入一个类似金饭碗的公司,那么在你工作5年内至少以1年的频率进行面试经历,我不是指一年*率的跳槽,是面试,面...阅读全文

posted @ 2012-11-25 17:17 每当变幻时 阅读(1305) | 评论 (5) 编辑

理解IO_InputStream-我们到底能走多远系列(16)
摘要: 我们到底能走多远系列(16)扯淡: 我觉得不断的重复学习基础才是成长的关键。可能有一天我们拥有几十个框架的经验,可是却一个组件也无法设计一下,应该算不是很好吧。主题:知识点:1.byte 类型Java byte 类型的取值范围是-128~127 byte是1个字节,也就是8位 最高位是符号位,其它七位来表示它的值 最大的应该是0111 1111,因为第一位是符号位,0表示正数。0111 1111即127 负数部分是由补码体现的,补码的是绝对值,取反,加上符号位,加1。 -1表示:1000 0001 它的补码是:1111 1111。 1000 0000也就是数字-128。2,ja...阅读全文

posted @ 2012-11-18 21:50 每当变幻时 阅读(1148) | 评论 (3) 编辑

Java 阶段面试 知识点合集 - 我们到底能走多远系列(15)
摘要: 我们到底能走多远系列(15)扯淡:这些知识点来源是通过面试涉及到的,面的公司不多,知识点涉及也不多,我每次面试后都在备忘录里写下有用的东西,集合起来分享一下,因为是知识点,所以就不出什么面试题目啦。不涉及任何公司,也不谈论面经,纯粹是学习而已。 《我们到底能走多远系列》的阶段性目标已经达到啦,15个,先给自己鼓励一下吧。 有目的性学习的确会让人不偷懒,能让人在短时间里努力,自我激励的方式很多,每天花点时间做一件事对你肯定有帮助,好吧先讲一个故事,口痒了,哈哈。 可能很多朋友都听过了,没关系,再听一遍,你就可以熟练的讲给你的朋友们听了。 从前有两个和尚他们分别住在河对岸的两个庙里,每天他...阅读全文

posted @ 2012-11-13 23:37 每当变幻时 阅读(1628) | 评论 (2) 编辑

Tomcat加载类机制 - 我们到底能走多远系列(14)
摘要: 我们到底能走多远系列(14)扯淡:各位,你们的钱是省出来的吗?前几天一个同事(女)结婚,了解了下情况:男女一起买房接*80*方,实际房子是60*,四五十万的首付吧,加上装潢,男女全家,连外公外婆都出力出钱,搞定,圆满买房结婚啦。大多数的我们都会走这么一段路或已经走了这一段路。我不知道你们听到这样普通的八卦会是怎样的感受。刚看完《温州一家人》的前两集,买家送女儿出国学习,带着儿子老婆以捡破烂开始温州的新生活。虽然是电视剧,但上点年纪的都应该知道我们的上一辈很多人都有类似的魄力,对,因为那时候穷,穷怕了,拼了,现在一无所有,输了,还是一无所有,不怕。可是现在不一样了,我们稍稍付出点努力就可以温饱,阅读全文

posted @ 2012-11-11 01:05 每当变幻时 阅读(1416) | 评论 (6) 编辑

Tomcat容器结构及Pipeline机制 -我们到底能走多远系列(13)
摘要: 我们到底能走多远系列(13)扯淡: 有机会有时间的话,我是会看那个职来职往的电视节目,个人觉得比其他一些娱乐节目对自己有帮助一些,我主要关注的还是现在人们的价值观,因为只有了解别人的价值观,也就是别人想要的,才可以更好的和他们沟通交流,从而达到目的。想必大家都听过,励志牛人说过:想要别人给你想要的,谈论他想要的。 有时候,“慎言”是很好的习惯,多聆听,多观察,就像《闻香识女人》中的台词一样:day we stop looking, is the day we die.主题: 直接学习tomcat的valve好像有点突兀,所以还是先去了解下tomcat的一个核心的组件containerco...阅读全文

posted @ 2012-11-03 20:11 每当变幻时 阅读(892) | 评论 (1) 编辑

java XML解析-我们到底能走多远系列(12)
摘要: 我们到底能走多远系列(12)扯淡:距离 我们到底能走多远系列 的阶段性目标15篇,已经很*了,100篇的最终目标还很远。 最*,接到个面试通知,做了份笔试,大部分都是基础题目,有java的,sql的。看来下一次换工作的征途又要开始啦,哈哈。 只记得有个简单的小题目了,把ABC,变成CBA。很简单的基础题,只是我实在记不起那个笔试题里的其他题目了。哎...实现:package code.stu.string;public class Inversion { public static void main(String[] args) { System.out.p...阅读全文

posted @ 2012-10-29 23:30 每当变幻时 阅读(502) | 评论 (2) 编辑

InternalInputBuffer处理HTTP请求行-Tomcat源码-我们到底能走多远系列(11)
摘要: 我们到底能走多远系列(11)扯淡: 最*行情不好吗?跳槽的比较少嘛,哈哈。有些人一直抗拒跳槽,觉得弊端很多:什么业务积累,职务,别人觉得你不可靠啊等等。我就想:这一辈子时间有限,何必为了一颗可以乘凉的树,放弃穿过森林的机会呢?祝在跳槽路上的朋友 顺利!(ps:个人喜欢面试 那种刺激感) 最爽不顾躺着,最美不过夕阳。秋天的夕阳是一年中最华丽的,各位不要错过哦。主题: 在tomcat中,一个http请求,会被送到Http11Processor类,执行这个类的process(Socket theSocket) 处理的传入的Socket,Socket里面装的就是http消息。 tomcat是如...阅读全文

posted @ 2012-10-21 22:12 每当变幻时 阅读(963) | 评论 (2) 编辑

Tomcat StringManager阅读学习 -我们到底能走多远系列(10)
摘要: 我们到底能走多远系列(10)扯淡:空闲时间不多,扯淡时间久更少了。主题: 先了解下两个所谓的知识点:ResourceBundle 和MessageFormat在项目里用的得心应手的properites文件,大多要用到这两个类吧。java.util.ResourceBundlejava.text.MessageFormat1,ResourceBundle解析资源文件分两步:1加载资源文件,2获取资源文件中的信息// 加载资源文件ResourceBundle resource = ResourceBundle.getBundle("messages");// 获取资源文件中的信阅读全文

posted @ 2012-10-17 21:33 每当变幻时 阅读(1296) | 评论 (2) 编辑

Tomcat加载servlet类文件 -我们到底能走多远系列(9)
摘要: 我们到底能走多远系列(9)扯淡: 最*晚上在看魅力记录的《玄奘之路》,可以了解些历史,理解些文化,比其它的节目好多了,推荐各位欣赏。 上周读书,有两个故事: 第一个: 有一个养鸡场几千只鸡分别排列的被关在狭小的鸡笼里,鸡笼的前面有传送带为小鸡送来食物,后面有传送带送走产下的鸡蛋。可是却注意到有几十只小鸡在外面“逍遥”,还有饲养员在给他们喂食。 于是就问:是否需要帮忙吧这些鸡赶到笼子里去呢? 饲养员回答说:哦,这些鸡是在外面养着的。要是笼子里的那些鸡看不到有的鸡自由自在的生活,它们就会失去信心,不下蛋。没有这些放养的鸡,其它的就会放弃一切,然后死去。 突然惊异的发现我们的生活方式和...阅读全文

posted @ 2012-10-13 00:41 每当变幻时 阅读(976) | 评论 (0) 编辑

How Tomcat Works 学习-我们到底能走多远系列(8)
摘要: 我们到底能走多远系列(8)扯淡: 我们到底能走多远?是想提醒自己不要停止学习和博客的更新,这个系列会一直和web开发有关,我的目标是写完100个。慢慢来,阶段性目标15个吧。哈哈 学得好不如做的好,做得好不如扯得好啊!主题: 在上一轮学习中:Servlet-我们到底能走多远系列(7) 发现要想理解web中的servlet,还是需要深入学习servlet 容器:tomcat(因为它是开源的嘛!) 为了不迷失在tomcat茫茫的源码中,我先学习下最外围的一些知识,然后先把《How Tomcat Works 》第一章看了。有人评论说这本书就是代码太多,我到很喜欢这个写作风格,程序员嘛,代码就...阅读全文

posted @ 2012-10-10 22:51 每当变幻时 阅读(1254) | 评论 (2) 编辑

Servlet-我们到底能走多远系列(7)
摘要: 我们到底能走多远系列(7)祝大家长假快乐,工作的时候拼命,休息享受的时候也请拼命。今天不扯淡了,过完假期再来和你们扯,哈哈!Servlet的核心类图如下:上面的servlet只是接口,相当于描述了servlet的标准,也就是说与协议无关。而HttpServlet的实现是根据Http协议来完成的。看下面的截图: 打开源码看后发现大多数接口和抽象类,那么真正的实现都在哪呢?在servlet容器源代码里,即类似Tomcat这样的servlet容器。 所以我觉得可以这样理解Servlet的作用:它提供了操控的按钮,这些按钮一旦被安装到Servlet容器里面,我们就可以通过这些按钮操控servlet..阅读全文

posted @ 2012-09-29 20:57 每当变幻时 阅读(1068) | 评论 (2) 编辑

Servlet的Context与Config
摘要: Servlet的Context与Config2009-11-25 作者: 编辑:崔晓帆 点击进入论坛关键词:ServletContextConfig 对于web容器来说,Servlet Context接口定义了一个Servlet环境对象,这个对象定义了一个在Servlet引擎上的Servlet的视图。通过使用这个对象,Servlet可以记录事件,得到资源并得到来自Servlet的引擎类。 Servlet容器在启动时会加载web应用,并为每个web应用创建唯一的Servlet context对象,可以把Servlet Context看成是一个Web应用的服务器端组件的共享内存,在Servl...阅读全文

posted @ 2012-09-29 00:26 每当变幻时| 编辑

servlet原理2
摘要: Servlet运行在Servlet容器中,由容器负责Servlet实例的查找及创建工作,并按照Servlet规范的规定调用Servlet的一组方法,这些方法也叫生命周期的方法。具体调用过程如下图所示:Servlet生命周期详解 如上图所示,Servlet的生命周期可以分为四个阶段,即装载类及创建实例阶段、初始化阶段、服务阶段和实例销毁阶段。下面针对每个阶段的编程任务及注意事项进行详细的说明。(1)装载类及创建实例 客户端向Web服务器发送一个请求,请求的协议及路径必须遵守如下的格式:http://serverip:port/application-path/resource-path 其中,s阅读全文

posted @ 2012-09-28 00:21 每当变幻时| 编辑

多线程_传送带-我们到底能走多远系列(6)
摘要: 我们到底能走多远系列(6) 光阴似箭,我居然也到了需要相亲的年龄。 我已经开始准备向人生成熟的阶段前进,就像一个苹果,从青苹果到成熟,要经历很多,要面对很多,这一路,每一位在我身边的朋友都有你的功劳。 加油,各位,我们都不孤单。 ----------------------------------------------------------------java多线程的一些理解:关于同步方法,我们不得不需要记住:1,线程在一个对象上,两个线程不可以调用两个不同的同步方法2,当一个同步方法已经执行,其他线程还是能够调用这个对象的非同步方法。 selvlet中为了提高响应速度,采用的...阅读全文

posted @ 2012-09-09 15:24 每当变幻时 阅读(1073) | 评论 (3) 编辑

多线程_分析词频-我们到底能走多远系列(5)
摘要: 我们到底能走多远系列(5)一日不扯淡,便觉空虚迷茫: 西瓜不是切出来的,房子不是画出来的,人生却是磨出来的。 前天,坐旁边的8年C++高手辞职走人了。磨了8年的男人,有些谢顶,有些憔悴。 我想就算每天学到的只有一点点,8年也能悟出不少东西来吧。我想他虽不是及其努力的那种,但凭着对编程技术或者知识的爱好,不自然的会去学到很多东西。这几个月接触下来他,发现他几个工作上的几个点: 1,编码的时候,基本是不用google的。(google都是在编码开始前搞的大概) 2,出错,异常,问题的时候,直接看底层实现。因为有时候他会抱怨怎么没有提供底层代码包。 3,很关注和自己作用的技术有关的新闻,...阅读全文

posted @ 2012-09-02 22:27 每当变幻时 阅读(1237) | 评论 (5) 编辑

剪切文件_配置文件修改-我们到底能走多远系列(4)
摘要: 我们到底能走多远系列(4)扯淡: 不知道有多少人喜欢听着音乐写点代码的?我是其中一个。以前在公司的时候期望能买个好点的MP3什么的心无旁骛的写点代码,领点工资。生活总是没有想象得美好。程序员要处理的事有很多不是坐在舒服的椅子上,喝点咖啡或绿茶,敲几行代码能解决的。 是不是大家都是容易放弃的人呢?反正我是的,上个月,看本书看了2章,就搁置了。上个星期开始尝试听voa,临*的3天就荒废了。今天继续吧。 园子里读到过一篇怎样找出自己人生的终极目标:用一个小时,勿打扰的思考,不断记下浮现脑海的答案,列出表格。作者认为用这种方式在最后能够发现每个人自己一生的目标。从而开启一个不一样的人生旅程。不知...阅读全文

posted @ 2012-08-26 19:27 每当变幻时 阅读(215) | 评论 (0) 编辑

BufferedInputStream-我们到底能走多远系列(3)
摘要: 我们到底能走多远系列(3)扯淡:现在项目里的java代码,都是封装,封装,再封装。在没有空闲的赶工编码,几年后会感觉学不动,毕竟少了很多思考的时间。也基本不会去研究代码的底层实现。时间一长就会觉得自己什么也不会。一个大型的项目,一般不可能只用java实现,可能会用到C,C++,shell,python等等。单单一个web就要学很多,jsp,jquery,javascript,html,css,各种开源的不开源的框架,各种web服务器,数据库等等等。java程序员的确容易迷茫,但精通一样吧,怕找不到工作,全学吧,怕一直是码农。其实,我觉得大多数的人都只是希望能做到“工程师”,解决问题的人。我看到阅读全文

posted @ 2012-08-22 21:51 每当变幻时 阅读(1263) | 评论 (0) 编辑

遍历文件夹内的文件(我们到底能走多远系列2)
摘要: 我们到底能走多远系列(2)遍历指定路径下的文件,文件和文件夹需要区分。为了把文件名和是否为文件夹记录下来,实现一个modelpackage web.method.file.model;public class FileModel { // 是否为文件夹 private boolean isDirectory; // 文件名 private String fileNmae; public FileModel(boolean isDirectory, String fileNmae) { super(); this.isDi...阅读全文

posted @ 2012-08-18 23:45 每当变幻时 阅读(233) | 评论 (0) 编辑

java IO 解析
摘要: 来自网络资源:1. 基于字节的输入流 2. 基于字节的输出流3. 基于字符的输入流4. 基于字符的输出流阅读全文

posted @ 2012-08-16 21:55 每当变幻时 阅读(204) | 评论 (0) 编辑

java IO 流的学习(我们到底能走多远系列1)
摘要: 我们到底能走多远系列(1)“我们到底能走多远系列”:开始我的java之路。我要挖出这个地道,离开这里。IO入门代码阅读:字节流: private void writeTxt(String path, String value) throws IOException{ OutputStream fos = new FileOutputStream(path);//构造方法1 fos.write(value.getBytes()); fos.close(); } private void readTxt(String path) thro...阅读全文

posted @ 2012-08-15 21:47 每当变幻时 阅读(232) | 评论 (0) 编辑

java File 基础学习
摘要: 下面的这么多方法组建起来可以写出很多有用的功能了吧?为了很方便的代表文件的概念,以及存储一些对于文件的基本操作,在java.io包中设计了一个专门的类——File类。 在File类中包含了大部分和文件操作的功能方法,该类的对象可以代表一个具体的文件或文件夹,所以以前曾有人建议将该类的类名修改成FilePath,因为该类也可以代表一个文件夹,更准确的说是可以代表一个文件路径。 下面介绍一下File类的基本使用。 1、File对象代表文件路径File类的对象可以代表一个具体的文件路径,在实际代表时,可以使用绝对路径也可以使用相对路径。下面是创建的文件对象示例。 public File(String阅读全文

posted @ 2012-08-09 23:20 每当变幻时 阅读(79) | 评论 (0) 编辑

servlet阅读
摘要: Servlet它担当客户请求(Web浏览器或其他HTTP客户程序)与服务器响应的中间层每一个servlet都会继承HttpServlet:(1) init() 方法 在 Servlet 的生命期中,仅执行一次 init() 方法。它是在服务器装入 Servlet 时执行的。 可以配置服务器,以在启动服务器或客户机首次访问 Servlet 时装入 Servlet。 无论有多少客户机访问 Servlet,都不会重复执行 init() 。 缺省的 init() 方法通常是符合要求的,但也可以用定制 init() 方法来覆盖它,典型的是管理服务器端资源。 例如,可能编写一个定制 init() 来...阅读全文

posted @ 2012-08-07 23:32 每当变幻时 阅读(129) | 评论 (0) 编辑

post and get
摘要: 来自:http://www.cnblogs.com/zhishan/articles/2441893.htmlGET和POST区别和用法多人都分不清GET与POST的区别,以及什么时候用GET?什么时候用POST? GET和POST两种方法都是将数据送到服务器,但你该用哪一种呢? HTTP标准包含这两种方法是为了达到不同的目的。POST用于创建资源,资源的内容会被编入HTTP请示的内容中。例如,处理订货表单、在数据库中加入新数据行等。 当请求无副作用时(如进行搜索),便可使用GET方法;当请求有副作用时(如在数据库添加数据行),则用POST方法。一个比较实际的问题是:GET方法可能会产生很长的阅读全文

posted @ 2012-08-05 22:12 每当变幻时 阅读(97) | 评论 (0) 编辑

插入排序 来自《算法导论》
摘要: 《算法导论》应该是一本很好的书吧,希望能把他啃完。public class JustDoIt0804 { /** * 插入排序(来自《算法导论》) */ public static void main(String[] args) { int[] x = new int[]{4,2,1,5,7,9,1}; insertSort(x); for (int i = 0; i < x.length; i++) { System.out.print(x[i] + " "); } } ...阅读全文

posted @ 2012-08-04 22:36 每当变幻时 阅读(27) | 评论 (0) 编辑

合并两个有序数组(重新开始)
摘要: 在看分治算法的时候,想先自己写写合并的代码,还是不熟练啊!为了保持对代码的敏感度,要保持练习。加油!public class JustDoIt0803 { /** * 分治算法学习前准备 */ public static void main(String[] args) { int[] x = new int[]{1,4,5,33}; int[] y = new int[]{2,4,5,7,9,12,45,78}; int[] z = mergeArrays(x, y); for (int i = 0; i <...阅读全文

posted @ 2012-08-03 23:07 每当变幻时 阅读(57) | 评论 (0) 编辑

Java参数传递问题
摘要: 一个数组参数抛出的问题当时的情况是这样的: public static void test(Integer[] x){ x[1] = 99; } public static void main(String[] args) { Integer[] temp1 = new Integer[] {3, 4}; test(temp1);// 1 Integer[] temp2 = {5, 6}; test(temp2);// 2 } Normal 0 ...阅读全文

posted @ 2012-08-02 00:23 每当变幻时 阅读(928) | 评论 (0) 编辑

分治算法
摘要: 当我们求解某些问题时,由于这些问题要处理的数据相当多,或求解过程相当复杂,使得直接求解法在时间上相当长,或者根本无法直接求出。对于这类问题,我们 往往先把它分解成几个子问题,找到求出这几个子问题的解法后,再找到合适的方法,把它们组合成求整个问题的解法。如果这些子问题还较大,难以解决,可以再 把它们分成几个更小的子问题,以此类推,直至可以直接求出解为止。这就是分治策略的基本思想。百科上的一个例子:给你一个装有1 6个硬币的袋子。1 6个硬币中有一个是伪造的,并且那个伪造的硬币比真的硬币要轻一些。你的任务是找出这个伪造的硬币。为了帮助你完成这一任务,将提供一台可用来比较两组硬 币重量的仪器,利用这阅读全文

posted @ 2012-07-31 23:15 每当变幻时 阅读(101) | 评论 (0) 编辑

选择排序(selection sort)
摘要: 每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。public <T extends Comparable<T>> void sort(T[] array, boolean ascend) { int len = array.length; for (int i = 0; i < len; i++) { int selected = i; for (int j = i + 1; j < len; j++) { int compare = array[j].comp阅读全文

posted @ 2012-07-29 22:53 每当变幻时 阅读(29) | 评论 (0) 编辑

插入排序
摘要: 我想:这个大概和*时打双扣的时候拿牌排序的流程一样吧!插入排序就是每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕。 插入排序方法分直接插入排序和折半插入排序两种,这里只介绍直接插入排序,折半插入排序留到“查找”内容中进行。 图1演示了对4个元素进行直接插入排序的过程,共需要(a),(b),(c)三次插入。代码 public class InsertionSorter { public void Sort(int[] arr) { for (int i = 1; i < arr.Length; i++) { int t = arr[i]...阅读全文

posted @ 2012-07-29 19:58 每当变幻时 阅读(39) | 评论 (0) 编辑

数组排序(冒泡和快速)
摘要: public static void sort(int[] values){ int temp; for(int i=0 ; i < values.length ; ++i){ for(int j=0; j <values.length - i - 1; ++j){ if(values[j] > values[j + 1]){ temp = values[j]; ...阅读全文

posted @ 2012-02-13 21:17 每当变幻时 阅读(59) | 评论 (0) 编辑

final修饰符
摘要: 1、final类 final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为final类。 2、final方法 如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。 使用final方法的原因有二: 第一、把方法锁定,防止任何继承类修改它的意义和实现。 第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。 3、final变量(常量) 用final修饰的成员变量表示常量,值一旦给定就无法改变! final修饰的变...阅读全文

posted @ 2012-02-08 21:11 每当变幻时 阅读(123) | 评论 (0) 编辑

hashmap可以用null为键值
摘要: import java.util.HashMap;import java.util.Map;import java.util.TreeMap;public class TestMain { public static void main(String[] args) { // HashMap可以的键值可以是null, "". Map<String, String> strMap1 = new HashMap<String, String>(); strMap1.put(null, "1"); strMap1.put("&阅读全文

posted @ 2012-01-12 22:19 每当变幻时 阅读(316) | 评论 (0) 编辑

posted on 2013-03-18 22:34  HackerVirus  阅读(343)  评论(0编辑  收藏  举报