springスレッド池の使用

6263 ワード

1.TaskExectorインターフェースを知る
SpringのTaskExectorインターフェースはjava.util.co ncurrent.Exectorインターフェースと同じです。実際には、スレッド池を使用する際に、Java 5への依存を抽象化することが主な原因となります。このインターフェースは一つの方法だけexecuteであり、スレッド池の意味と構成に従ってタスクを実行する。最初にTaskExectorを作成したのは,必要に応じて他のSpringコンポーネントにスレッド池の抽象を提供するためである。例えば、Appliation Event Multicasterコンポーネント、JMSのAbstractMessage ListenerContinerとQuarzの統合は、TasExector抽象を使用してスレッドプールを提供しています。もちろん、あなたのBeanがスレッド行動を必要とするなら、この抽象層も使えます。
 
2.Task Exectorインターフェースの実現類
(1)SimpleAsyncTaskExector類
この実装はスレッドを再利用しない、または呼び出しごとに新しいスレッドを起動します。しかし、スレッドの合計制限を超えると、新しい呼び出しがブロックされ、リリースされるまでは、まだマージンの合計をサポートしています。本当の池が必要なら、下を見てください。
 
(2)SyncTaskExector類
この実現は非同期的に実行されない。これに対して、呼出が開始されるスレッドでは毎回実行される。主な用途はマルチスレッドが必要ない時、例えば簡単なtest caseです。
 
(3)コンカレントTaskExector類
この実装はJava 5 java.util.co ncurrent.Exector類のパッケージです。もう一つの代替があり、ThreadPoolTaskExector類は、Exectorの配置パラメータをbean属性として露出しています。Conccurrent TaskExectorを使用する必要は少ないですが、ThreadPoolTaskExectorが不足している場合、Conccurrent TaskExectorは別の候補です。
(4)SimpleThreadPoolTaskExector類
この実装は実際にQuartzのSimpleThreadPool類のサブクラスであり、Springのライフサイクルのフィードバックを傍受します。ケーブルが必要な場合は、Quartzと非Quartzのコンポーネントを共同で使う場合、これはその典型的な用途です。
(5)ThreadPoolTaskExector類
これはjava.util.co ncurrentパッケージの代替または下り移植をサポートしていません。Dugg LeaとDawid Kurzynicは、java.util.co ncurrentの実装に対して異なるパッケージ構造を採用しており、それらが正しく動作しないことをもたらしています。この実現はJava 5環境でしか使えませんが、この環境で一番よく使われています。それが露出したbean propertiesはjava.util.co ncurrent.ThreadPool Exectorを配置するために使用できます。それをTaskExectorに包装します。もっと先進的なクラスが必要なら、例えばScheduledThreadPoolExectorなど、ConcerentTaskExectorを使って代替することを提案します。
(6)TimeTaskExector類
この実現はその背後にある実現としてTimerTaskを用いた。Sync TaskExectorとは違って、方法呼び出しは独立したスレッドで行われていますが、そのスレッドでは同期しています。
(7)Work Manager TaskExector類
この実装は、Common J WorkManagerを使ってその最下層として実現し、Spring contextにCommon J Work Managerアプリケーションを配置する最も重要なクラスです。Simple ThreadPoolTasExectorと同様に、このクラスはWorkManagerインターフェースを実現していますので、直接WorkManagerとして使用できます。
 
 
3.スレッド池DemoのThreadPoolTaskExector
(1)試験類の作成

package com.fczfr.spring.common.thread;

import org.springframework.core.task.TaskExecutor;

/**
 * Spring        
 * 
 * **/
public class Executor {
	private TaskExecutor taskExecutor;  
	  
    public void setTaskExecutor(TaskExecutor taskExecutor) {  
        this.taskExecutor = taskExecutor;  
    }  
  
    public void doExecute(Runnable runnable) {  
        this.taskExecutor.execute(runnable);  
    }  
}


package com.fczfr.spring.common.beans;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanFactoryUtil {
	public static BeanFactory getBeanFactory(){
		ClassPathXmlApplicationContext resource = new ClassPathXmlApplicationContext(
				new  String("applicationContext.xml")); 
		BeanFactory factory = resource; 
		return factory;
	}
}
appication.xmlの構成は以下の通りです。

<bean id="threadPoolTaskExecutor"  
        class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">  
        <property name="corePoolSize" value="5" /> <!--          (    ) -->  
        <property name="maxPoolSize" value="10" /> <!--            (          ) -->  
        <property name="queueCapacity" value="25" /> <!--         -->  
    </bean>  
    <bean id="executor" class="com.fczfr.spring.common.thread.Executor">  
         <property name="taskExecutor" ref="threadPoolTaskExecutor"></property>  
    </bean>  
試験種別の作成:

package com.fczfr.spring.common.test;

import org.springframework.beans.factory.BeanFactory;

import com.fczfr.spring.common.beans.BeanFactoryUtil;
import com.fczfr.spring.common.thread.Executor;

public class TestExecutor {

	/**
	 *    Executor 
	 */
	public static void main(String[] args) {
		BeanFactory factory = BeanFactoryUtil.getBeanFactory();
		Executor executor =(Executor)factory.getBean("executor");
		for (int i = 0; i < 25; i++) {
			executor.doExecute(new MessagePrinterTask("message: " + i));
		}
	}
}
class MessagePrinterTask implements Runnable {
	private String message;

	public MessagePrinterTask(String message) {
		this.message = message;
	}

	public void run() {
		try {
			System.out.println("start-->" + message);
			Thread.sleep(1000);
			System.out.println("end  -->" + message);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

運転効果は以下の通りです。
start-->メッセージ:0
start-->メッセージ:1
start->メッセージ:2
start->メッセージ:3
start->メッセージ:4
end  -->メッセージ:0
start->メッセージ:5
end  -->メッセージ:3
start-->メッセージ:6
end  -->メッセージ:4
end  -->メッセージ:1
end  -->メッセージ:2
start-->メッセージ:7
start->メッセージ:8
start-->メッセージ:9
end  -->メッセージ:5
start-->メッセージ:10
end  -->メッセージ:6
start-->メッセージ:11
end  -->メッセージ:7
end  -->メッセージ:8
end  -->メッセージ:9
start->メッセージ:12
start-->メッセージ:13
start-->メッセージ:14
end  -->メッセージ:12
end  -->メッセージ:14
end  -->メッセージ:13
start-->メッセージ:15
end  -->メッセージ:10
end  -->メッセージ:11
start-->メッセージ:16
start-->メッセージ:17
start-->メッセージ:18
start-->メッセージ:19
end  -->メッセージ:19
start-->メッセージ:20
end  -->メッセージ:15
start-->メッセージ:21
end  -->メッセージ:18
start->メッセージ:22
end  -->メッセージ:17
start-->メッセージ:23
end  -->メッセージ:16
start-->メッセージ:24
end  -->メッセージ:23
end  -->メッセージ:20
end  -->メッセージ:21
end  -->メッセージ:22
end  -->メッセージ:24