SPRING中的線程池

記錄一句:用多線程處理和消息隊列來處理大數據量操作,文件操作,或者併發。)
多線程併發處理起來通常比較麻煩,如果你使用spring容器來管理業務bean,事情就好辦了多了。spring封裝了Java的多線程的實現,你只需要關注於併發事物的流程以及一些併發負載量等特性,具體來說如何使用spring來處理併發事務:

1.瞭解 TaskExecutor接口

Spring的TaskExecutor接口等同於java.util.concurrent.Executor接口。 實際上,它存在的主要原因是爲了在使用線程池的時候,將對Java 5的依賴抽象出來。 這個接口只有一個方法execute(Runnable task),它根據線程池的語義和配置,來接受一個執行任務。最初創建TaskExecutor是爲了在需要時給其他Spring組件提供一個線程池的抽象。 例如ApplicationEventMulticaster組件、JMS的 AbstractMessageListenerContainer和對Quartz的整合都使用了TaskExecutor抽象來提供線程池。 當然,如果你的bean需要線程池行爲,你也可以使用這個抽象層。
2. TaskExecutor接口的實現類

(1)SimpleAsyncTaskExecutor 類

這個實現不重用任何線程,或者說它每次調用都啓動一個新線程。但是,它還是支持對併發總數設限,當超過線程併發總數限制時,阻塞新的調用,直到有位置被釋放。如果你需要真正的池,請繼續往下看。

(2)SyncTaskExecutor類

這個實現不會異步執行。相反,每次調用都在發起調用的線程中執行。它的主要用處是在不需要多線程的時候,比如簡單的test case。

(3)ConcurrentTaskExecutor 類

這個實現是對Java 5 java.util.concurrent.Executor類的包裝。有另一個備選, ThreadPoolTaskExecutor類,它暴露了Executor的配置參數作爲bean屬性。很少需要使用ConcurrentTaskExecutor, 但是如果ThreadPoolTaskExecutor不敷所需,ConcurrentTaskExecutor是另外一個備選。

(4)SimpleThreadPoolTaskExecutor 類

這個實現實際上是Quartz的SimpleThreadPool類的子類,它會監聽Spring的生命週期回調。當你有線程池,需要在Quartz和非Quartz組件中共用時,這是它的典型用處。

(5)ThreadPoolTaskExecutor 類

它不支持任何對java.util.concurrent包的替換或者下行移植。Doug Lea和Dawid Kurzyniec對java.util.concurrent的實現都採用了不同的包結構,導致它們無法正確運行。 這個實現只能在Java 5環境中使用,但是卻是這個環境中最常用的。它暴露的bean properties可以用來配置一個java.util.concurrent.ThreadPoolExecutor,把它包裝到一個TaskExecutor中。如果你需要更加先進的類,比如ScheduledThreadPoolExecutor,我們建議你使用ConcurrentTaskExecutor來替代。

(6)TimerTaskExecutor類

這個實現使用一個TimerTask作爲其背後的實現。它和SyncTaskExecutor的不同在於,方法調用是在一個獨立的線程中進行的,雖然在那個線程中是同的。

(7)WorkMana
gerTaskExecutor類

3.文件配置

    <!-- modify the parameters of thread pool -->
   <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
               <!-- 核心線程數 -->
     <property name="corePoolSize" value="5"/>      
                <!-- 最大線程數 --> 
     <property name="maxPoolSize" value="20"/>
                <!-- 隊列最大長度 -->
     <property name="queueCapacity" value="10"/>
         <!-- 線程池維護線程所允許的空閒時間,默認爲60s -->
     <property name="keepAliveSeconds" value="120"/>
   </bean> 

然後把taskExecutor注入到所需要的類中

<bean id="threadPoolTask" class="cn.springmvc.query.ThreadPoolClass">
         <property name="taskExecutor" ref="taskExecutor"></property>  
    </bean>

就可以在cn.springmvc.query.ThreadPoolClass類中使用線程池了

ThreadPoolTaskExecutor taskExecutor = ThreadPoolClass.getTaskExecutor();
CommentNotification commentNotification = new CommentNotification(tid, userid, commentType, pid, postAuthorId);
   taskExecutor.execute(commentNotification);
   //其中CommentNotification 如下定義
    public static class CommentNotification implements  Runnable {

        int tid;
        int userid;
        int commentType;
        int pid;
        int postAuthorId;

        public CommentNotification( int tid,  int userid,  int commentType,  int pid,
                int postAuthorId) {
            this.tid = tid;
            this.userid = userid;
            this.commentType = commentType;
            this.pid = pid;
            this.postAuthorId = postAuthorId;
        }

        public void run() {
            System.out.println("Thread name: " + Thread.currentThread().getName() + " is running");
            addCommentNotification(tid, userid, commentType, pid, postAuthorId);
        }
    }
//其中addCommentNotification方法如下定義


    private static void addCommentNotification(final int tid, final int userid, final int commentType, final int pid,
            int postAuthorId) {


        ForumThread ft = QueryThreadView.getFormThreadInfo(tid);
        int authorid = commentType == UserResponse ? postAuthorId : ft.getAuthorid();
        System.out.println("addCommentNotification userid : " + userid + " authorid : " + authorid);
        //用戶和(文章/評論)作者不是同一人,則添加通知
        if (userid != authorid) {
            CommonMember commonMember = QueryUserInfo.getCommonMemberInfo(userid);
            addResponseNotification(tid, userid, pid, commonMember.getPf_field8(),commonMember.getUsername(), authorid, ft.getSubject(), commentType);
            UserNotification.updateNewPrompts(authorid,UserNotification.post, UserNotification.add);
            QueryFriend.updateFriendNum(userid, authorid);
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章