Question

Je suis en train d'écrire une application Java EE en utilisant Struts et Spring.Dans l'une des opérations il est lourd traitement de base de données, et donc des problèmes de performances.Ce que je veux savoir est ce que je peux utiliser le multithreading ici?Je pense que la spécification Java EE ne permet pas coutume fils à être créé en dehors de ceux créés par le Serveur (j'utilise Weblogic).Merci de me guider à travers ce.

Était-ce utile?

La solution

Cette question apparaît de temps en temps.

Conformément à la spécification, il n'est pas autorisé.Le meilleur de la page pour regarder, c'est celui-ci: Q/R:J2EE Restrictions

Cela dit, il existe des moyens pour frayer fils, especiall dans Weblogic avec l' WorkManager.

Voir ces questions:

Le fait que le premier des objectifs EJB ne devrait pas beaucoup d'importance, et le dernier sujet de l'accès au système de fichiers est d'environ restrictions générales.

Espérons que cela aide.

Autres conseils

La manière recommandée de créer des threads dans un environnement Java EE est avec l'API Utils de la concurrence, qui fait partie de la spécification EE7.

En utilisant cette API, votre nouveau three sera créé et géré par le conteneur, garantissant que tous les services EE sont disponibles pour votre thread (par exemple, la sécurité, les transactions).

Les exemples ci-dessous sont extraits de mon propre site ici et ici

en utilisant un géantExecutetorservice

Pour créer un nouveau thread à l'aide d'un gantEdexecuterservice, créez d'abord un objet de tâche implémentant appelable. Dans la méthode des appels (), nous définirons le travail que nous voulons effectuer dans un fil séparé.

public class ReportTask implements Callable<Report> {

    Logger logger = Logger.getLogger(getClass().getSimpleName());

    public Report call() {
        try {
            Thread.sleep(3000);
        catch (InterruptedException e) {
            logger.log(Level.SEVERE, "Thread interrupted", e);
        }
        return new Report();
    }
}

Ensuite, nous devons invoquer la tâche en le transmettant à la méthode Soumettre () de la ManagementExecUtorservice.

@Stateless
public class ReportBean {

    @Resource
    private ManagedExecutorService executorService;

    public void runReports() {
        ReportTask reportTask = new ReportTask();
        Future<Report> future = executorService.submit(reportTask);
    }
}

à l'aide d'un gestionnaire de gestion

Créez d'abord une tâche exécutable qui définira quel travail doit être effectué en arrière-plan.

public class ReportTask implements Runnable {

    Logger logger = Logger.getLogger(getClass().getSimpleName());

    public void run() {
        try {
            //do your background task
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            logger.log(Level.SEVERE, "Thread interrupted", e);
        }
    }
}

Pour obtenir un thread géré de conteneur, nous demandons simplement à la gestion gérées pour un nouveau fil et transmettez-le notre instance annulée. Pour démarrer le fil, nous appelons le début ().

@Stateless
public class ReportBean {

    @Resource
    private ManagedThreadFactory threadFactory;

    public void runReports() {
        ReportTask reportTask = new ReportTask();
        Thread thread = threadFactory.newThread(reportTask);
        thread.start();
    }
}

Ces restrictions sont en place surtout parce que Java EE et EJB souhaitent soutenir le regroupement transparent.Par exemple, un serveur d'un cluster ne doit pas modifier les fichiers car ces modifications ne peuvent pas être facilement reflétées vers d'autres serveurs.Pour les fils, il y a la question s'il doit y avoir un fil par grappe ou par serveur.Ces filets ne peuvent également pas être facilement surveillés par le serveur d'applications.

Cela dit, il devrait être possible de créer des threads, des connexions de socket ou d'accéder au système de fichiers dans un serveur Java EE, comme dans une application normale.

Si vous devez exécuter plusieurs threads ici, c'est une suggestion (ou une autre manière) avec le piscine de contrôle simple:

1 - Passez votre contexte (EJB) en tant que paramètre sur votre méthode (point d'extrémité de repos, planificateur, méthodes de défaut)

2 - Contrôlez l'état avec un planificateur complémentaire ou des drapeaux d'entité 3 - Soyez prudent avec le volume de données / traitement

4 - Recommandations: métriques, journaux et tests, tests, tests sont fortement recommandés

5 - Ce code est sur Springboot mais a été testé dans JBoss (avec modifications) sous Contexte EJB - Test soigneusement

6 - Utilisez / Modifiez comme vous le souhaitez: (Envoyer des suggestions / commentaires)

basocontrolexecutor.java

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;


public class BaseControlExecutor {

    private final ScheduledThreadPoolExecutor poolExec = new ScheduledThreadPoolExecutor(2);

    public void execWithTimeout(final Runnable runnable, long timeout,
            TimeUnit timeUnit) throws Exception {
        execWithTimeout(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                runnable.run();
                return null;
            }
        }, timeout, timeUnit);
    }

    public <T> T execWithTimeout(Callable<T> callable, long timeout,    TimeUnit timeUnit) throws Exception {

        final Future<T> future = poolExec.submit(callable);

        try {
            return future.get(timeout, timeUnit);
        } catch (TimeoutException e) {
            future.cancel(true);
            throw e;
        } catch (ExecutionException e) {
            Throwable t = e.getCause();
            if (t instanceof Error) {
                throw (Error) t;
            } else if (t instanceof Exception) {
                throw (Exception) t;
            } else {
                throw new IllegalStateException(t);
            }
        }
    }
}

finPointControlrest.java

import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicLong;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@RestController
@RequestMapping(value = "/report")
@Api(tags = "Endpoint of Future")
public class EndpointControlRest extends BaseControlExecutor {

    Logger logger = LoggerFactory.getLogger(EndpointControlRest.class);

    //single metric of execution
    protected final AtomicLong counter = new AtomicLong();

    @GetMapping(path = "/withThread", produces = { "application/json" })
    @ApiOperation(value = "Return Hello count.")
    public String greeting() {

        Long countRunner = counter.incrementAndGet();
        String json = ""; //or EJB context to use in Thread - becareful

        new Thread(() -> {

            try {
                execWithTimeout(new Runnable() {
                    @Override
                    public void run() {

                        Instant start = Instant.now();
                        logger.info("Report init - " + countRunner);

                        //generating reports
                        generateBackgroundReport(json);

                        logger.info("Report End - " + countRunner);

                        Instant finish = Instant.now();
                        long timeElapsed = Duration.between(start, finish).toMillis();

                        logger.info("###DEBUG - " + countRunner + " - OK |Time exe: " + timeElapsed);

                    }
                }, 120, TimeUnit.SECONDS);
            } catch (TimeoutException e) {
                logger.info("###DEBUG - " + countRunner + " - Timeout - " + e.getMessage());
            } catch (Exception e) {
                logger.info("###DEBUG - " + countRunner + " - Exception - " + e.getMessage());
            }
        }).start();

        logger.info("####DEBUG - Rest call released");
        return "Hello " + countRunner;
    }

    public String generateBackgroundReport(String json){

        //simulating work
        Long x = 0L;
        for(Long i = 0L; i < 1000000000L; i ++){
            x = i + 1;
        }
        logger.info("####DEBUG -report: " + x);
        return "OK";
    }
}

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top