我试图了解如何处理异常处理。我有我的下面的Singleton类连接到cassandra,初始化第一次调用的所有元数据,然后启动一个定期的后台线程,每15分钟更新一次我们的元数据。
public class CassUtils {
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
private final CassSession cassSession;
private static class Holder {
private static final CassUtils INSTANCE = new CassUtils();
}
public static CassUtils getInstance() {
return Holder.INSTANCE;
}
private CassUtils() {
CassConfig config = Utils.getConfig();
try {
this.cassSession = new CassSession(config);
initializeMetadata(); // initializes metadata on the very first call
} catch (Exception ex) {
// log error
throw new IllegalStateException("cannot initialize metadata: " + ex.getMessage());
}
}
private void startScheduleTask() {
scheduler.scheduleAtFixedRate(new Runnable() {
public void run() {
try {
List<ProcessMetadata> processMetadata = getProcessMeta();
List<ClientMetadata> clientMetadata = getClientMeta();
List<ProcMetadata> procMetadata = getProcMeta();
if (!processMetadata.isEmpty() && !clientMetadata.isEmpty())
MetadataManager.setMetadata(processMetadata, clientMetadata, procMetadata);
} catch (Exception ex) {
// log error
}
}
}, 30, 15, TimeUnit.MINUTES);
}
private void initializeMetadata() {
List<ProcessMetadata> processMetadata = getProcessMeta(true);
List<ClientMetadata> clientMetadata = getClientMeta();
List<ProcMetadata> procMetadata = getProcMeta();
if (processMetadata.isEmpty() || clientMetadata.isEmpty() || procMetadata.isEmpty()) {
throw new IllegalStateException(); // is it ok to throw exception without any message here?
}
MetadataManager.setMetadata(processMetadata, clientMetadata, procMetadata);
startScheduleTask();
}
如果有任何问题,我需要通知正在调用此单例的调用方。
CassSession
抛出异常,因为这是连接到cassandra的类,并且由于某种原因它无法连接到cassandra(大多数情况下它永远不会发生),那么我在{中捕获异常{1}}在catch
类中阻止并向用户发送CassUtils
,并在其中显示消息。IllegalStateException
(我们将永远)连接到cassandra,但在CassSession
方法中,我们所有的元数据都是空的,那么我就不会# 39;我想继续前进,所以我扔了initializeMetadata
而没有任何消息。这可以吗?因为最终它会被IllegalStateException
类的catch
块捕获,这会给调用用户抛出异常。如何在单例情况下处理异常处理,以便我们可以通知正在调用此单例的呼叫者。 CassUtils
是被抛到这里的正确例外吗?上述情况将在初始化时的第一次调用期间发生。还有更好的方法吗?
答案 0 :(得分:1)
您正在使用静态/类初始化来创建ClassUtils
实例。作为一般规则:
Error
被抛出。即使在您能够捕获此错误的上下文中,您也会遇到初始化失败的类。 JVM不会重试初始化,并且类......以及依赖它的任何其他类都将无法使用。因此,如果您要处理此问题,则需要在静态初始化期间捕获并(适当地)处理异常。
接下来的问题是,如果要向CassUtils
单例的用户报告失败,那么getInstance()
必须返回CassUtils
(或者可能是子类)的实例能够:
CassUtils
API上的实例方法的调用者。这是可能的,但很复杂。
IMO是不受欢迎的。我认为你最好不要试图恢复。将Casandra会话初始化失败视为致命错误。如果你不能这样做,那么getInstance()
方法应该是抛出/重新抛出“我们被破坏”的异常的方法。至少,这避免了任何CassUtils
方法的任何调用者都需要处理“我们被破坏”的异常。
有没有人提到过单身人士是个坏主意?请考虑使用依赖注入。