Javaスレッドイメージ、title = "java</em>thread"、width = 300、height = 200

ここでは、Springで「

threading

」を行う方法を示す3つの例を示します。自明のためのコードを参照してください。

1. Spring Java Threadsの例


Thread`を拡張して単純なJavaスレッドを作成し、Springのコンテナによって

@ Component`を介して管理します。 Beanのスコープは ”

prototype

“でなければならず、各リクエストは新しいインスタンスを返し、各スレッドを実行します。

PrintThread.java

package com.mkyong.thread;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("prototype")
public class PrintThread extends Thread{

    @Override
    public void run() {

        System.out.println(getName() + " is running");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(getName() + " is running");
    }

}

AppConfig.java

package com.mkyong.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages="com.mkyong.thread")
public class AppConfig{
}

App.java

package com.mkyong;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.mkyong.config.AppConfig;
import com.mkyong.thread.PrintThread;

public class App
{
    public static void main( String[]args )
    {

        ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);

        PrintThread printThread1 = (PrintThread) ctx.getBean("printThread");
        printThread1.setName("Thread 1");

        PrintThread printThread2 = (PrintThread) ctx.getBean("printThread");
        printThread2.setName("Thread 2");

        PrintThread printThread3 = (PrintThread) ctx.getBean("printThread");
        printThread3.setName("Thread 3");

        PrintThread printThread4 = (PrintThread) ctx.getBean("printThread");
        printThread4.setName("Thread 4");

        PrintThread printThread5 = (PrintThread) ctx.getBean("printThread");
        printThread5.setName("Thread 5");

        printThread1.start();
        printThread2.start();
        printThread3.start();
        printThread4.start();
        printThread5.start();

    }
}

出力 – 注文は毎回変わります、これはスレッドです:)

Thread 3 is running
Thread 2 is running
Thread 1 is running
Thread 5 is running
Thread 4 is running
Thread 2 is running
Thread 4 is running
Thread 5 is running
Thread 3 is running
Thread 1 is running

2. SpringスレッドプールSpring非管理Beanの例

Springの `ThreadPoolTask​​Executor`を使用してスレッドプールを作成します。実行中のスレッドは、Springコンテナによって管理される必要はありません。

PrintThread.java – このスレッドはSpring、NO @ Componentで管理されていません

package com.mkyong.thread;

public class PrintTask implements Runnable{

    String name;

    public PrintTask(String name){
        this.name = name;
    }

    @Override
    public void run() {

        System.out.println(name + " is running");

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(name + " is running");
    }

}

Spring-Config.xml – XMLファイルのThreadPoolTask​​Executor

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.1.xsd">

    <bean id="taskExecutor"
        class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <property name="corePoolSize" value="5"/>
        <property name="maxPoolSize" value="10"/>
        <property name="WaitForTasksToCompleteOnShutdown" value="true"/>
    </bean>

</beans>

App.java

package com.mkyong;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import com.mkyong.thread.PrintTask;

public class App {
  public static void main(String[]args) {

    ApplicationContext context = new ClassPathXmlApplicationContext("Spring-Config.xml");
    ThreadPoolTaskExecutor taskExecutor = (ThreadPoolTaskExecutor) context.getBean("taskExecutor");
    taskExecutor.execute(new PrintTask("Thread 1"));
    taskExecutor.execute(new PrintTask("Thread 2"));
    taskExecutor.execute(new PrintTask("Thread 3"));
    taskExecutor.execute(new PrintTask("Thread 4"));
    taskExecutor.execute(new PrintTask("Thread 5"));

   //check active thread, if zero then shut down the thread pool
    for (;;) {
        int count = taskExecutor.getActiveCount();
        System.out.println("Active Threads : " + count);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (count == 0) {
            taskExecutor.shutdown();
            break;
        }
    }

    }
}

出力 – 注文は毎回変わります。

Thread 1 is running
Thread 2 is running
Thread 3 is running
Thread 4 is running
Active Threads : 4
Thread 5 is running
Active Threads : 5
Active Threads : 5
Active Threads : 5
Active Threads : 5
Thread 2 is running
Thread 1 is running
Thread 3 is running
Thread 4 is running
Thread 5 is running
Active Threads : 0

3. Springスレッドプール+ Spring管理Beanの例

この例では

ThreadPoolTask​​Executor`をもう一度使っていて、

@ Component`を介してそのスレッドをSpring管理Beanとして宣言しています。

以下の

PrintTask2`はSpring管理Beanです。必要なBeanを簡単に

@ Autowired`することができます。

PrintTask2.java

package com.mkyong.thread;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("prototype")
public class PrintTask2 implements Runnable{

    String name;

    public void setName(String name){
        this.name = name;
    }

    @Override
    public void run() {

        System.out.println(name + " is running");

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(name + " is running");

    }

}

AppConfig.java – SpringコンフィグレーションファイルのThreadPoolTask​​Executor

package com.mkyong.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Configuration
@ComponentScan(basePackages = "com.mkyong.thread")
public class AppConfig {

    @Bean
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
        pool.setCorePoolSize(5);
        pool.setMaxPoolSize(10);
        pool.setWaitForTasksToCompleteOnShutdown(true);
        return pool;
    }

}

App.java

package com.mkyong;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import com.mkyong.config.AppConfig;
import com.mkyong.thread.PrintTask2;

public class App {
  public static void main(String[]args) {

    ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
    ThreadPoolTaskExecutor taskExecutor = (ThreadPoolTaskExecutor) context.getBean("taskExecutor");

    PrintTask2 printTask1 = (PrintTask2) context.getBean("printTask2");
    printTask1.setName("Thread 1");
    taskExecutor.execute(printTask1);

    PrintTask2 printTask2 = (PrintTask2) context.getBean("printTask2");
    printTask2.setName("Thread 2");
    taskExecutor.execute(printTask2);

    PrintTask2 printTask3 = (PrintTask2) context.getBean("printTask2");
    printTask3.setName("Thread 3");
    taskExecutor.execute(printTask3);

    for (;;) {
        int count = taskExecutor.getActiveCount();
        System.out.println("Active Threads : " + count);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (count == 0) {
            taskExecutor.shutdown();
            break;
        }
    }

   }
}

出力 – 注文は毎回変わります。

Thread 1 is running
Thread 2 is running
Thread 3 is running
Active Threads : 2
Active Threads : 3
Active Threads : 3
Active Threads : 3
Active Threads : 3
Thread 1 is running
Thread 3 is running
Thread 2 is running
Active Threads : 0

上記のプログラムを改善するためにあなたのコメントを愛してください。

ソースコードをダウンロードする

ダウンロードする –

Spring-Thread-Example.zip

(22 KB)