Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javaee规范与多线程_Java_Multithreading_Jakarta Ee - Fatal编程技术网

javaee规范与多线程

javaee规范与多线程,java,multithreading,jakarta-ee,Java,Multithreading,Jakarta Ee,我正在使用Struts和Spring编写一个JavaEE应用程序。在其中一个操作中,存在繁重的数据库处理,因此存在性能问题。我想知道的是我可以在这里使用多线程吗?我认为JavaEE规范不允许在服务器创建的线程之外创建自定义线程(我使用Weblogic)。请引导我完成这个问题。这个问题偶尔会出现 根据规范,它未经授权。最好看的一页是: 也就是说,有很多方法可以产生线程,特别是在使用WorkManager的Weblogic中 见以下问题: 事实上,第一个目标是EJB并不重要,最后一个目标是

我正在使用Struts和Spring编写一个JavaEE应用程序。在其中一个操作中,存在繁重的数据库处理,因此存在性能问题。我想知道的是我可以在这里使用多线程吗?我认为JavaEE规范不允许在服务器创建的线程之外创建自定义线程(我使用Weblogic)。请引导我完成这个问题。

这个问题偶尔会出现

根据规范,它未经授权。最好看的一页是:

也就是说,有很多方法可以产生线程,特别是在使用
WorkManager
的Weblogic中

见以下问题:

事实上,第一个目标是EJB并不重要,最后一个目标是关于访问文件系统的一般限制


希望有帮助。

这些限制主要是因为JavaEE和EJB希望支持透明集群。例如,群集的一台服务器不应修改文件,因为这些更改无法轻松镜像到其他服务器。对于线程,问题是每个集群或服务器应该有一个线程。应用服务器也无法轻松监视这些线程


也就是说,应该可以像在普通应用程序中一样在Java EE服务器中创建线程、套接字连接或访问文件系统。

在Java EE环境中创建线程的推荐方法是使用并发Utils API,它是EE7规范的一部分

通过使用此API,您的新线程将被创建,并由容器进行管理,从而确保所有EE服务对您的线程可用(例如安全性、事务)

下面的例子取自我自己的网站和

使用ManagedExecutorService

要使用ManagedExecutorService创建新线程,首先创建一个实现Callable的任务对象。在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();
    }
}
要获得容器管理的线程,我们只需向ManagedThreadFactory请求一个新线程,并将可运行实例传递给它。要启动线程,我们称之为start()


如果您需要运行多个线程,这里有一个简单控件池的建议(或替代方法):

1-将上下文(EJB)作为参数传递给方法(rest端点、调度程序、默认方法)

2-使用补充计划程序或实体标志控制状态 3-小心数据/处理量

4-建议:指标、日志和测试,强烈建议进行测试

5-此代码在SpringBoot上,但在EJB上下文-测试下在Jboss中进行了测试(经过修改)

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);
            }
        }
    }
}
import java.util.concurrent.Callable;
导入java.util.concurrent.ExecutionException;
导入java.util.concurrent.Future;
导入java.util.concurrent.ScheduledThreadPoolExecutor;
导入java.util.concurrent.TimeUnit;
导入java.util.concurrent.TimeoutException;
公共类BaseControlExecutor{
private final ScheduledThreadPoolExecutor poolExec=新ScheduledThreadPoolExecutor(2);
public void execWithTimeout(最终可运行、长超时、,
TimeUnit(TimeUnit)引发异常{
execWithTimeout(新的可调用(){
@凌驾
公共对象调用()引发异常{
runnable.run();
返回null;
}
},超时,时间单位);
}
public T execWithTimeout(可调用、长超时、TimeUnit TimeUnit)引发异常{
最终未来=poolExec.submit(可调用);
试一试{
返回future.get(超时,时间单位);
}捕获(超时异常e){
future.cancel(true);
投掷e;
}捕获(执行例外){
可丢弃的t=e.getCause();
if(t instanceof Error){
抛出(错误)t;
}else if(异常的t实例){
抛出(异常)t;
}否则{
抛出新的非法状态异常(t);
}
}
}
}
EndpointControlRest.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";
    }
}
import java.time.Duration;
导入java.time.Instant;
导入java.util.concurrent.TimeUnit;
导入java.util.concurrent.TimeoutException;
导入java.util.concurrent.AtomicLong;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
导入org.springframework.web.bind.annotation.GetMapping;
导入org.springframework.web.bind.annotation.RequestMapping;
导入org.springframework.web.bind.annotation.RestController;
导入io.swagger.annotations.Api;
导入io.swagger.annotations.api操作;
@RestController
@请求映射(value=“/report”)
@Api(tags=“未来的端点”)
公共类EndpointControlRest扩展了BaseControlExecutor{
Logger Logger=LoggerFactory.getLogger(EndpointControlRest.class);
//执行的单一度量
受保护的最终AtomicLong计数器=新的AtomicLong();
@GetMapping(path=“/withThread”,products={“应用程序/json”})
@ApiOperation(value=“Return Hello count.”)
公共字符串问候语(){
Long countRunner=counter.incrementAndGet();
字符串json=”“;//或要在线程中使用的EJB上下文-小心
新线程(()->{
试一试{
execWithTimeout(新的Runnable(){
@凌驾
公开募捐{
即时开始=即时。现在();
logger.info(“报告初始化-”+countRunner);
//生成报告
generateBackgroundReport(json);
logger.info(“报告结束-”+countRunner);
即时完成=即时。立即();
@Stateless
public class ReportBean {

    @Resource
    private ManagedThreadFactory threadFactory;

    public void runReports() {
        ReportTask reportTask = new ReportTask();
        Thread thread = threadFactory.newThread(reportTask);
        thread.start();
    }
}
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);
            }
        }
    }
}
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";
    }
}