频道栏目
首页 > 程序开发 > 综合编程 > 组件/库 > 正文
知识库--StandardContext+backgroundProcess(60)
2016-12-26 10:07:10      个评论    来源:qfzhangwei的专栏  
收藏   我要投稿

The backgroundProcess Method

A context needs the help of other components, such as a loader and a manager. Often these components require a separate thread that handles background processing. For instance, a loader that support auto reload needs a thread to periodically check the timestamps of all class and JAR files in WEB-INF. A manager needs to a thread to check the expiration time of the session objects it manages. In Tomcat 4 those components end up having their own threads.

To save resources, Tomcat 5 uses a different approach. All background processes share the same thread. If a component or a Container needs to have an operation done periodically, all it needs to do is write the code in its backgroundProcess method.

The shared thread is created in a ContainerBase object. The ContainerBase class calls its threadStart method in its start method.

    protected void threadStart(){
        if(thread != null)
            return;
        if(backgroundProcessorDelay <= 0)
            return;
        threadDone = false;
        String threadName = "ContainerBackgroundProcessor["+toString()+"]";
        thread = new Thread(new ContainerBackgroundProcessor(),threadName);
        thread.setDaemon(true);
        thread.start();
    }

The threadStart method constructs a new thread by passing an instance of ContainerBackgroundProcessor class that implements java.lang.Runnable.

    protected class ContainerBackgroundProcessor implements Runnable{
        public void run(){
            while(!threadDone){
                try{Thread.sleep(backgroundProcessorDelay*1000L);}catch(InterruptedException e){;}
            }
            if(!threadDone){
                Container parent = getMappingObject();
                ClassLoader cl = Thread.currentThread().getContextClassLoader();
                if(parent.getLoader()!=null){
                    cl = parent.getLoader().getClasssLoader();
                }
                processChildren(parent,cl);
            }
        }
    }

protected void processChildren(Container container,ClassLoader cl){
    try{
        if(container.getLoader()!=null){
            Thread.currentThread().setContextClassLoader(container.getLoader().getClassLoader()));
        }//设置线程变量
        container.backgroundProcess();//execute逻辑
    }catch(Throwable t){log.error("Exception invoking periodic operation:",t);
    }finally{
        Thread.currentThread().setContextClassLoader(cl);
    }
    Container[] children = container.findChildren();
    for(int i =0;i<children.length;i++){
        if(children[i].getBackgroundProcessorDelay()<=0){//到期了
        processChildren(children[i],cl);//递归调用

        }
    }
}

The ContainerBackgroundProcessor class is an inner class of ContainerBase. Inside its run method is while loop that periodically calls its processChildren method. The processChildren method in turn calls the** backgroundProcess method and the **processChildren method of each of its children. By implementing the backgroundProcess method, a child class of ContainerBase can have a dedicated thread for running periodic tasks, such as checking classes’timestamps or expiry times of session objects.

public void backgroundProcess(){
    if(!started)
        return;
    count = (count +  1)%managerChecksFrequency;
    if((getManager()!=null) &&(count ==0)){
        try{
            getManager().backgroundProcess();//session 管理
        }catch(Exception e){
            log.warn("Unable to perform background process on manager", x);
        }
    }
    if(getLoader()!=null){
        if(reloadable && (getLoader().modified())){
            try{
                Thread.currentThread().setContextClassloader(StandardContext.class.getClassLoader());
                reload();//现成使用最新的加载器 reload
            }finally{
                if(getLoader()!=null){
                    Thread.currentThread().setContextClassLoader(getLoader().getClassLoader());
                }
            }
        }
        if(getLoader() instanceof WebappLoader){
            ((WebappLoader)getLoader()).closeJARs(false));
        }
    }
}

It should be clear how StandardContext helps its associated manager and loader with their periodic tasks.//context帮助他们周期性完成tasks

点击复制链接 与好友分享!回本站首页
上一篇:APP使用的一些第三方库
下一篇:知识库--Server + Service
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站