月写意&随月

导航

线程管理工具类(支持单线程队列以及多线程并发)

       我们开发的过程中,如果某个动作耗时过长,我们又不想等待;如果某个动作需要定时不断执行;如果我们想同时做几件事情;我们就需要使用到线程了。线程里面运用最多的,无疑就是单线程的队列管理,或者多线程并发执行了。这种情况有1个经典的应用场景,也是个人至今做的唯一的一个J2ME项目中的运用:处理http请求。

       那个是我工作第一年做的唯一的一个项目,对手机客户端开发感兴趣的应该有所了解,是移动的一个定制项目:手机阅读。现在已经全国推广使用了,各种机型应该都可以下载到适用的客户端。那个时候真的是个菜鸟,刚刚毕业,写起代码来就像摸着石头过河,一步一徘徊。团队里面有个工作第2年的算是老鸟的一个写手,处理http请求这块的内容,因为客户端与服务器之间是用http通讯的,所有数据都需要从服务端获取,在手机上展示,所以http工具类的重要性不言而喻,经过1个多月的反复推倒重来,测试修改,终于完工。其实代码并不多,核心的也就1个类,几百行而已。算下来,一个月平均每天也就码了40多行。至此,我对华为的那个团队负责人是深感佩服:他在编码开工会上说:“一个好的程序员,1天能写出的优秀代码也不过是百行不到,所以你们不要追求速度,慢慢来,质量最重要。”那个时候我们还在嗤之以鼻,1天少说也写个几百上千行啊,百行不到不是笑死人。之后大半年的时间,果然证明姜还是老的辣。我们花了2个月完成整个客户端代码的编写,却花了6个月在代码的review和重构上,也就是在那个时候,编码的一些好的习惯,以及对于代码质量的重视深深扎根在我心间。一直延续到如今的工作中。

      当然很多做web项目的人不会有机会对代码做如此扣的动作,因为review和重构意味着工作量的增加,劳动成本的提升,开销的加大,这些都是你的上司所不希望见到的。他们常常希望你做出来的东西只要能用,满足条件即可,不会去关注代码的质量问题,时间是第一位的,因为要上线,要验收,要赚钱。当然,一些强大的web服务器足以弥补很多代码上的不足,所以一份好的代码越来越难出现在这样的队伍中。我目前处于的环境就是这样,万幸的是:我处于公司java组的框架开发团队,这使得我有机会延续之前好的习惯,感谢老天 ,没有让我去做枯燥无味的重复体力劳动(具体项目的开发)。

     闲话不多说,回归主题。因为近期用到了线程,所以回想了之前项目中的使用场景:多线程并发(同时进行多本书的下载);单线程队列(一个页面上面普通的http请求,进行了队列的管理)。下面贴出核心代码。

包含2个文件:ThreadManageUtil ,ThreadObject 大家可以直接拷贝使用

import java.util.ArrayList;
import java.util.List;

/**
 * 线程管理工具类
 *
 * @作者 komojoemary
 * @version [版本号, 2011-2-24]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class ThreadManageUtil implements Runnable
{
    /**
     * 请求队列(用于单线程)
     */
    private static List<ThreadObject> requestList = null;

    /**
     * 同步对象(用于单线程)
     */
    private static Object object = new Object();

    /**
     * ThreadManageUtil对象的实例(用于单线程)
     */
    private static ThreadManageUtil instance = null;

    /**
     * 当前的请求对象
     */
    private ThreadObject currentRequest = null;

    /**
     * 是否为多线程运行
     */
    private boolean isMultiThread = false;

    /**
     * 运行线程
     *
     * @param 无
     * @return 无
     * @exception/throws 无
     * @see 无
     */
    public void run() {
        // 如果为多线程
        if (isMultiThread) {
            runHandle();
        }
        // 非多线程
        else {
            while (true) {
                // 如果不为空则为超时需要重连的请求,不从队列里重新获取
                if (currentRequest == null) {
                    synchronized (object) {
                        // 队列不为空
                        if (requestList.size() > 0) {
                            // 从队列中获取请求
                            currentRequest = (ThreadObject) requestList.get(0);
                            // 从请求队列中将当前请求删除
                            requestList.remove(0);
                        }
                        else {
                            try {
                                // 队列为空则交出对象锁,等待唤醒
                                object.wait();
                                continue;
                            }
                            catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
                runHandle();
                currentRequest = null;
            }
        }
    }

    /**
     *
     * 请求过程处理 过程
     *
     * @param 无
     * @return 无
     * @exception/throws 无 无
     * @see 无
     */
    private void runHandle() {
        try {
            currentRequest.handleOperation();
            Thread.yield();
        }
        catch (Exception ce) {
            ce.printStackTrace();
        }
    }

    /**
     *
     * 启动线程 当用单线程多任务排队请求时,将请求添加至请求队列中。当请求的是多线程时,开辟一个新的线程
     *
     * @param request
     *            请求对象
     * @return 无
     * @exception/throws 无
     */
    public static void sendRequest(ThreadObject request) {
        // 多线程
        if (request.isMultiThread()) {
            ThreadManageUtil downloadHttp = new ThreadManageUtil();
            downloadHttp.isMultiThread = true;
            downloadHttp.currentRequest = request;
            new Thread(downloadHttp).start();
        }
        else {
            // 单线程请求排队
            if (instance == null) {
                // 在当前线程对象为空时才进行线程初始化操作,同时初始化队列
                instance = new ThreadManageUtil();
                requestList = new ArrayList<ThreadObject>();
                new Thread(instance).start();
            }
            insertReqList(request);
        }
    }

    /**
     *
     * 请求添加方法
     *
     * @param request
     *            需要添加的请求
     * @return 无
     * @exception/throws 无
     * @see 无
     */
    private static void insertReqList(ThreadObject request) {
        synchronized (object) {
            requestList.add(request);
            object.notify();
        }
    }

}

 


/**
 * 线程执行对象
 *
 * @作者 komojoemary
 * @version [版本号, 2011-2-24]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public abstract class ThreadObject
{
    /**
     * 是否多线程
     */
    private boolean multiThread = false;

    /**
     * 是否处理完成
     */
    private boolean isOk = false;

    /**
     * 线程处理操作
     *
     * @exception/throws [违例类型] [违例说明]
     * @see [类、类#方法、类#成员]
     */
    public abstract Object handleOperation();

    public boolean isMultiThread() {
        return multiThread;
    }

    public void setMultiThread(boolean multiThread) {
        this.multiThread = multiThread;
    }

    public boolean isOk() {
        return isOk;
    }

    public void setOk(boolean isOk) {
        this.isOk = isOk;
    }

}

posted on 2011-11-07 22:24  月写意&随月  阅读(888)  评论(1编辑  收藏  举报