具有单线程执行程序的RESTful Web服务的体系结构?

Gug*_*upf 1 java rest lifecycle web-services executor

我想知道什么是具有单线程执行程序的RESTful Web服务的最佳体系结构.

我的目标 :

  1. 调用RESTful Web服务
  2. Web服务在线程队列中添加任务,并按1执行所有任务1.

instanciated对象的生命周期非常重要(必须只有一个线程队列).我知道RESTful Web服务生命周期是"每个请求"(类似于我认为的@RequestScoped),所以我看到两个选项:

选项1 :

public class RestService {
    protected final static Executor executor;
    protected final static Implementation1 impl1;
    protected final static Implementation2 impl2;

    static {
        executor = Executors.newSingleThreadExecutor();
        impl1 = new Implementation1();
        impl2 = new Implementation2();
    }
}

@Path("/servicename")
public class MyService extends RestService {
    @POST
    @Path("/compute")
    public void compute(){
        executor.execute(new Runnable(){
            public void run(){
                impl1.compute();
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

选项2:

@Singleton
public class RestService {
    private Executor executor;
    private Implementation1 impl1;
    private Implementation2 impl2;

    public RestService () {
        executor = Executors.newSingleThreadExecutor();
        impl1 = new Implementation1();
        impl2 = new Implementation2();
    }

    public void execute(Runnable run){
        executor.execute(run);
    }

    public Implementation1 getImplementation1(){
        return impl1;
    }

    public Implementation2 getImplementation2(){
        return impl2;
    }

}

@Path("/servicename")
public class MyService {

    @Inject
    private RestService rs;

    @POST
    @Path("/compute")
    public void compute(){
        rs.execute(new Runnable(){
            public void run(){
                rs.getImplementation1().compute();
            }
        });
    }
} 
Run Code Online (Sandbox Code Playgroud)

对于选项1,我不确定静态场的"生命周期".我应该使用哪个选项?你会怎么做?

谢谢

编辑: 选项3(由EJB容器处理的线程)和"排序"并不重要:

@Singleton
public class RestService {
    private final Executor executor;
    private final Implementation1 impl1;
    private final Implementation2 impl2;

    public RestService () {
        executor = Executors.newSingleThreadExecutor();
        impl1 = new Implementation1();
        impl2 = new Implementation2();
    }

    public void compute1(){
        executor.execute(new Runnable(){
            public void run(){
                impl1.compute();
            }
        });
    }

    public void compute2(){
        executor.execute(new Runnable(){
            public void run(){
                impl2.compute();
            }
        });
    }

}

@Path("/servicename")
public class MyService {

    @Inject
    private RestService rs;

    @POST
    @Path("/compute1")
    public void compute1(){
        rs.compute1();
    }

    @POST
    @Path("/compute2")
    public void compute2(){
        rs.compute2();
    }
} 
Run Code Online (Sandbox Code Playgroud)

我认为选项3仍然比选项1和2更好.

duf*_*ymo 6

我认为这样做是个坏主意.线程应该由您的容器处理,而不是您的代码.

如果要在Java EE应用服务器上进行部署,则应该让它处理线程.

如果要在Netty或vert.x等非阻塞I/O服务器上进行部署,则应该让它处理线程.

在任何情况下你都不应该管理线程.

加载.class时实例化静态字段.它们没有像实例那样的"生命周期".在类加载器删除.class文件之前,不会清除它们.

如果你必须有这种行为,我要么使用JMS队列来订购处理,要么使用生产者/消费者deque来管理它.您希望处理是异步的.让REST服务将令牌或收据返回给客户端,让他们回来查看处理完成的时间.如果线条很长,你将无法知道他们的衬衫什么时候准备就绪.收据让他们回来检查他们的结果何时可用.