문제

Struts와 Spring을 사용하여 Java EE 응용 프로그램을 작성하고 있습니다.작업 중 하나에서는 무거운 데이터베이스 처리가 가능하며 따라서 성능 문제가 있습니다.내가 알고 싶은 것은 여기에서 다중 스레딩을 사용할 수 있습니까?Java EE 사양은 서버가 생성 한 사용자가 생성 한 사용자 (iblogic)를 생성 할 수없는 사용자 정의 스레드를 허용하지 않습니다.이것을 통해 나를 안내하십시오.

도움이 되었습니까?

해결책

이 질문은 한 번 팝업됩니다.

사양에 따라 승인되지 않았습니다. 가장 좋은 페이지는 이것입니다. Q / A : J2EE 제한

, ThePsiall, Especiall

다음 질문을 참조하십시오 :

첫 번째 하나가 EJB가 그렇게 중요하지 않아야하고 파일 시스템에 대한 액세스에 대한 마지막 하나는 일반적인 제한 사항에 관한 것입니다.

그것은 도움이되기를 바랍니다.

다른 팁

Java EE 환경에서 스레드를 만드는 권장되는 방법은 EE7 사양의 일부인 동시성 Utils API와 함께 있습니다.

이 API를 사용하여 새 스레드가 생성되고 컨테이너가 관리하므로 모든 EE 서비스가 모든 EE 서비스가 스레드 (예 : 보안, 트랜잭션)가 사용할 수 있음을 보장합니다.

아래의 예는 내 자신의 사이트에서 여기에서 찍은 것입니다 여기

을 사용하여

ManagedExecUtorService를 사용하여 새 스레드를 만들려면 먼저 호출 할 수있는 작업 개체를 만듭니다. call () 메서드 내에서 우리는 별도의 스레드에서 수행 할 작업을 정의합니다.

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();
    }
}
.

그런 다음 ManagedExeCutorService의 제출 () 메소드에만 해당 작업을 호출해야합니다.

@Stateless
public class ReportBean {

    @Resource
    private ManagedExecutorService executorService;

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

managedThreadFactory 사용

먼저 백그라운드에서 작업을 수행 할 작업을 정의 할 실행 가능한 작업을 만듭니다.

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);
        }
    }
}
.

컨테이너 관리 스레드를 얻으려면 ManagedThreadFactory에 새 스레드를 요청하고 runnable 인스턴스를 전달하기 만하면됩니다. 스레드를 시작하려면 시작 () 호출 ().

@Stateless
public class ReportBean {

    @Resource
    private ManagedThreadFactory threadFactory;

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

Java EE와 EJB가 투명한 클러스터링을 지원하기를 원하기 때문에 대부분이 제한 사항이 있습니다.예를 들어 클러스터의 한 서버는 이러한 변경 사항을 다른 서버로 쉽게 미러링 할 수 없으므로 파일을 수정해서는 안됩니다.스레드의 경우 클러스터 당 하나의 스레드가 있거나 서버 당 하나의 스레드가 있어야하는 경우 질문이 있습니다.이 스레드는 응용 프로그램 서버에서 쉽게 모니터링 할 수 없습니다.

은 정상적인 응용 프로그램에서와 마찬가지로 Java EE 서버에서 스레드, 소켓 연결을 만들거나 파일 시스템에 액세스하는 것이 가능해야합니다.

여러 스레드를 실행 해야하는 경우 간단한 제어 풀이있는 제안 (또는 대안 방식)이 있습니다.

1 - Context (EJB)를 메서드에 매개 변수로 전달합니다 (REST 끝점, 스케줄러, 기본값의 메서드)

2 - 보완 스케줄러 또는 엔티티 플래그로 상태 제어 3 - 데이터 / 처리의 양에주의하십시오

4 - 권장 사항 : 메트릭, 로그 및 테스트, 테스트, 테스트가 강력하게 권장됩니다

5 -이 코드는 SpringBoot에 있지만 JBoss (수정 사항 포함)에서 EJB 컨텍스트에서 테스트 - 신중하게 테스트

6 - 원하는대로 사용 / 수정 : (제안 / 댓글 보내기)

basecontrolexecutor.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);
            }
        }
    }
}
.

endpointcontrollest.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";
    }
}
.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top