Java 使用调用多个服务的 ExecutorService 的代码设计
Java Code Design Using ExecutorService That Calling Mutliple Services
我正在尝试 运行 15 个并行服务,每个服务将向不同的客户群发送邮件。提取标准将因每个服务而异
服务 1、服务 2、服务 3....服务 15。每个 class 扩展 NotificationService class.
NotificationService class 有方法 extractRecipients()、sendMail()、sendSMS()、logNotification()。
所有服务 classes[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) {
}
}
使用执行器服务的invokeAll。
一些需要改进的地方(未完成):
我假设 Service1、Service2...classes 派生自 NotificationService,覆盖了 process
方法。
匿名接口实现 of 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 class。此代码然后减少为:
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
的调用者,同时将新任务添加到执行器 forever。
如果每次执行都会向客户发送一封电子邮件,那么他已经被淹没了。
每分钟调用 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();
}
}
另一种方法是使用 one ScheduledExecutorService,您可以在该服务上安排每个服务N 每分钟执行一次。
public void startService() {
try {
List<Bean> list = getServicesNotificationList();
ExecutorService service = Executors.newFixedThreadPool(list.size); here list size should be 15
for (int i=0; i < list.size(); i++) {
service.submit(new NotificationService(conn, list[i]));
}
service.shutdown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
我正在尝试 运行 15 个并行服务,每个服务将向不同的客户群发送邮件。提取标准将因每个服务而异
服务 1、服务 2、服务 3....服务 15。每个 class 扩展 NotificationService class.
NotificationService class 有方法 extractRecipients()、sendMail()、sendSMS()、logNotification()。
所有服务 classes[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) {
}
}
使用执行器服务的invokeAll。
一些需要改进的地方(未完成):
我假设 Service1、Service2...classes 派生自 NotificationService,覆盖了 process
方法。
匿名接口实现 of 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 class。此代码然后减少为:
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
的调用者,同时将新任务添加到执行器 forever。
如果每次执行都会向客户发送一封电子邮件,那么他已经被淹没了。
每分钟调用 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();
}
}
另一种方法是使用 one ScheduledExecutorService,您可以在该服务上安排每个服务N 每分钟执行一次。
public void startService() {
try {
List<Bean> list = getServicesNotificationList();
ExecutorService service = Executors.newFixedThreadPool(list.size); here list size should be 15
for (int i=0; i < list.size(); i++) {
service.submit(new NotificationService(conn, list[i]));
}
service.shutdown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}