Бесконечный l oop класса обслуживания предотвращает создание bean-компонента другого класса обслуживания - PullRequest
0 голосов
/ 14 июля 2020

У меня 3 класса обслуживания (пока предположим, что A, B, C). Каждый из них на самом деле представляет собой нить. По моему требованию у каждого из них должно быть бесконечное l oop. Но всякий раз, когда я запускаю класс обслуживания с бесконечным l, oop bean-компонент других классов обслуживания не создается.

Если нет бесконечного l oop, создается bean-компонент каждого класса. Почему это происходит?

Предположим, это Служба А.

@Service
@Log4j2
public class A implements Runnable {

    private boolean isRunning = true;

    @Override
    @PostConstruct
    public void run() {
        log.debug("A Thread Started!");

        while (isRunning) {

                // just a sleep for 2 sec
        }
    }
}

Предположим, что это Служба Б.

@Service
@Log4j2
public class B implements Runnable {

    private boolean isRunning = true;

    @Override
    @PostConstruct
    public void run() {
        log.debug("B Thread Started!");

        while (isRunning) {

                // just a sleep for 2 sec
        }
    }
}

Предположим, что это Служба C.

@Service
@Log4j2
public class C implements Runnable {

    private boolean isRunning = true;

    @Override
    @PostConstruct
    public void run() {
        log.debug("C Thread Started!");

        while (isRunning) {

                // just a sleep for 2 sec
        }
    }
}

И это мой основной класс:

@SpringBootApplication
@Log4j2
public class Main {

    @Autowired
    public ApplicationContext context;

    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }

    @Bean
    @PostConstruct
    public void createConnection() {

        log.debug("Connecting to Server...");
        // doing some staff
    }
}

Теперь, если я бегу вот так, всегда будет этот журнал:

2020-07-14 21:21:52:129 [main] DEBUG support.DefaultListableBeanFactory:217 - Creating shared instance of singleton bean 'a'
2020-07-14 21:21:52:130 [main] DEBUG service.ProcessorService:27 - A Thread Started!

Если я помещу какой-либо журнал в while l oop класса A, то отображаются только эти журналы.

Если я прокомментирую часть l oop класса A и сохраню класс следующим образом:

@Service
@Log4j2
public class A implements Runnable {

    private boolean isRunning = true;

    @Override
    @PostConstruct
    public void run() {
        log.debug("A Thread Started!");

       /* while (isRunning) {

                // just a sleep for 2 sec
        }*/
    }
}

затем получил это в журнале:

2020-07-14 21:30:31:198 [main] DEBUG support.DefaultListableBeanFactory:217 - Creating shared instance of singleton bean 'a'
2020-07-14 21:30:31:199 [main] DEBUG service.ProcessorService:27 - A Thread Started!
2020-07-14 21:30:31:199 [main] DEBUG support.DefaultListableBeanFactory:217 - Creating shared instance of singleton bean 'b'
2020-07-14 21:30:31:199 [main] DEBUG service.ReceivingProcessingService:46 - B Thread Started!

Если я прокомментирую часть l oop класса B, тогда будет запущен только каждый класс обслуживания. Не могу понять причину. Любая помощь будет оценена по достоинству.

Ответы [ 2 ]

0 голосов
/ 14 июля 2020

Так я изменил свой код. Теперь я использовал ThreadPoolExecutor.

@Configuration
@Log4j2
public class AppConfiguration {
    @Bean
    public ThreadPoolTaskExecutor taskExecutor() {
        log.debug("Config called of taskExecutor...");
        ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
        pool.setCorePoolSize(3);
        pool.setMaxPoolSize(3);
        pool.setWaitForTasksToCompleteOnShutdown(true);
        pool.initialize();
        return pool;
    }
}

Затем запустите службы следующим образом:

private void runServices() {
    ThreadPoolTaskExecutor executor = (ThreadPoolTaskExecutor) context.getBean("taskExecutor");

    A a = context.getBean(A.class);
    executor.execute(a);

    B b = context.getBean(B.class);
    executor.execute(b);

    C c = context.getBean(C.class);
    executor.execute(c);

    log.debug("Active Executor: " + executor.getActiveCount());
}

И классы обслуживания такие же, просто удалили аннотацию PostConstruct .

это Услуга А.

@Service
@Log4j2
public class A implements Runnable {

    private boolean isRunning = true;

    @Override
    public void run() {
        log.debug("A Thread Started!");

        while (isRunning) {

                // just a sleep for 2 sec
        }
    }
}

это Услуга Б.

@Service
@Log4j2
public class B implements Runnable {

    private boolean isRunning = true;

    @Override
    public void run() {
        log.debug("B Thread Started!");

        while (isRunning) {

                // just a sleep for 2 sec
        }
    }
}

это Услуга C.

@Service
@Log4j2
public class C implements Runnable {

    private boolean isRunning = true;

    @Override
    public void run() {
        log.debug("C Thread Started!");

        while (isRunning) {

                // just a sleep for 2 sec
        }
    }
}

Сейчас все работает нормально.

0 голосов
/ 14 июля 2020

Метод PostConstruct никогда не заканчивается в вашем случае, поэтому spring не может продолжить работу. В идеале вы должны создать отдельный класс MyRunnable, который реализует Runnable, и переопределить его метод run с вашим logi c и запустить новый поток в методе post-construct, как показано ниже:

@PostConstruct
public void init() {
  log.debug("Starting thread!");
  Thread myThread = new Thread(new MyRunnable());
  myThread.start();
}

Теперь вы можете удалить " реализует Runnable "из вашего класса обслуживания

...