Пример Spring и Java Thread

Пример Spring и Java Thread

Java thread images

Вот 3 примера, которые покажут вам, как выполнить «threading» в Spring. См код для самоочевидного.

1. Пример Spring + Java Threads

Создайте простой поток Java, расширивThread и управляемый контейнером Spring через@Component. Область действия 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 Thread Pool + пример неуправляемого компонента Spring

Использует SpringThreadPoolTaskExecutor для создания пула потоков. Выполняющий поток не обязательно управляется контейнером 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

В этом примере снова используетсяThreadPoolTaskExecutor, и поток объявляется как управляемый компонент Spring через@Component.

НижеPrintTask2 - это управляемый bean-компонент Spring, вы можете легко@Autowired использовать любые требуемые bean-компоненты.

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 КБ)