我正在尝试并行运行15个服务,每个服务将向不同的客户组发送邮件。提取标准将与每个服务不同

Service1,Service2,Service3 ...... Service15。每个类都扩展了NotificationService类。

NotificationService类具有方法extractRecipients(),sendMail(),sendSMS(),logNotification()。

所有Service类[1到15]都有process()方法,该方法将调用NotificationService方法并完成其工作。

这是设计Java代码的正确方法吗?

下面的代码看起来很丑陋,有什么聪明的方法可以处理。请有人帮我。

public void startService() {

try {
    ExecutorService service = Executors.newFixedThreadPool(3);

    for (;;) {
        service.submit(new Service1(conn) {
                    public Object call(){
                        try {
                            process(conn, param2); // Passing connection & obj
                        } catch (Exception e) {
                            throw e;
                        }
                        return null;
                    }
                });

        service.submit(new Service2(conn) {
                    public Object call(){
                        try {
                            process(conn, param2);
                        } catch (Exception e) {
                            throw e;
                        }
                        return null;
                    }
                });

        // like above i have 15 services. so its ugly.
    }

} catch (InterruptedException e) {
    e.printStackTrace();
}
}

public boolean process(Connection conn) throws Exception {
try {
// getRecipientsList(serviceID);

// sendMail(recipientsList);

// logNotificationDetails(notificationList);
} catch (Exception e) {
}
}

最佳答案

有待改进的地方(未完成):

我假设Service1,Service2,...类是从NotificationService派生的,并覆盖了process方法。

Callable<Object>的匿名接口实现:

service.submit(new Service1(conn) {
                public Object call(){
                    try {
                        process(conn, param2); // Passing connection & obj
                    } catch (Exception e) {
                        throw e;
                    }
                    return null;
                }
            });


应该移到NotificationService类。然后,此代码简化为:

service.submit(new Service1(conn)); // Will call Service1's "process" implementation
service.submit(new Service2(conn)); // Will call Service2's "process" implementation
...


编辑:

我想到的是这种设置:

abstract class NotificationService implements Callable<Object>{
  // ...

  // I don't know what types conn and param2 are, so ...
  protected abstract void process( ConnType conn, Param2Type param2 );

  @Override
  public Object call(){
      try {
              process(conn, param2); // Passing connection & obj
      } catch (Exception e) {
              throw e;
      }
      return null;
  }
}


然后,您可以覆盖Service1,Service2 ...中的process以其特定方式处理该过程。

class Service1 extends NotificationService{
    @Override
    protected void process( ConnType conn, Param2Type param2 ){
        // do process according to Service1's needs.
    }
}




无休止的循环:

for(;;){
   service.submit(...
}


当新的任务永久添加到执行器时,它将在该循环中阻止startService的调用者。

如果每次执行都导致向客户发送电子邮件,则该客户将被淹没。



每分钟呼叫startService

将产生一个新的ExecutorService,它将每分钟无休止地充满任务!

这不仅会向您的客户发送垃圾邮件,而且还会很快降低性能。



首先,您可以像这样进行更改:

public void startService() {

try {
    ExecutorService service = Executors.newFixedThreadPool(3);


        service.submit(new Service1(conn)); // assuming callable impl is moved

        service.submit(new Service2(conn));

        // like above i have 15 services. so its ugly.
    service.shutdown();

} catch (InterruptedException e) {
    e.printStackTrace();
}
}




一种替代方法是使用一个ScheduledExecutorService,在其上安排每个ServiceN每分钟执行一次。

09-28 02:10