SpringとJavaスレッドの例

SpringおよびJava Threadの例

Java thread images

Springで「threading」を実行する方法を示す3つの例を次に示します。 わかりやすいコードを参照してください。

1. Spring + Java Threadsの例

Threadを拡張して単純なJavaスレッドを作成し、@Componentを介してSpringのコンテナによって管理されます。 各リクエストが新しいインスタンスを返し、個々のスレッドを実行できるように、Beanスコープは「prototype」である必要があります。

PrintThread.java

package com.example.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.example.config;

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

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

App.java

package com.example;

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

import com.example.config.AppConfig;
import com.example.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のThreadPoolTaskExecutorを使用してスレッドプールを作成します。 実行中のスレッドは、Springコンテナによって管理される必要はありません。

PrintThread.java – This thread is not managed by Spring, NO @Component

package com.example.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 – ThreadPoolTaskExecutor in XML file



    
        
        
        
    

App.java

package com.example;

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

import com.example.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 Thread Pool + SpringマネージドBeanの例

この例では、ThreadPoolTaskExecutorを再度使用しており、スレッドを@Componentを介してSpringマネージドBeanとして宣言しています。

以下のPrintTask2はSpring管理のBeanであり、必要なBeanを簡単に@Autowiredできます。

PrintTask2.java

package com.example.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 – ThreadPoolTaskExecutor in Spring configuration file

package com.example.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.example.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.example;

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

import com.example.config.AppConfig;
import com.example.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)