我有两台linux机器。在一台机器上,我正在使用一个启动可执行文件的线程,另一个内部线程从可执行文件中读取数据并使用可执行文件中的值填充数据库,我使用myBatis来保存数据。稍后它会不断检查进程和内部线程是否已启动并运行。在另一台机器上,我有远程连接的数据库,每晚都在不断部署,因此数据库被删除并重新创建。因此,在此构建过程中数据库表不可用时会出现异常:
org.apache.ibatis.exceptions.PersistenceException
### Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
Table 'updates_table' doesn't exist
被抛出。然后,连续检查进程和内部线程的线程被终止,并且它停止检查。
任何人都可以帮助我如何处理未被杀死的线程,一旦数据库可用并运行它应该尝试重新填充表。当数据库不可用时,应始终继续尝试,直到数据库可用。
谢谢。
答案 0 :(得分:1)
考虑切换到一个系统,在该系统中,您可以从线程中将作业提交到Executor
:
public class MyThread extends Thread {
private final InputStream processStream;
private final Executor executor = Executors.newSingleThreadExecutor();
public MyThread(InputStream processStream) {
this.processStream = processStream;
}
@Override
public void run() {
while ([processStream has stuff]) {
final Object obj = // Get your object from the stream
executor.execute(new Runnable() {
@Override
public void run() {
// Do database stuff with obj
}
});
}
}
private static Object getSomethingFromStream(InputStream stream) {
// return something off the stream
}
}
如果Runnable
抛出异常,它将被记录,但不会被停止,它将继续执行队列中的下一个作业。另请注意,这是使用单线程执行程序,因此提交的所有内容将一次执行一次,并按照提交的顺序执行。如果您想要并发执行,请使用Executors.newFixedThreadPool(int)
或Executors.newCachedThreadPool()
。请注意,这解决了如何使线程保持活动状态。如果要在作业失败时重新提交runnable以重新执行,请将其run
方法更改为:
@Override
public void run() {
try {
// Do database stuff with obj
} catch (PeristenceException ex) {
// Try again
executor.execute(this);
}
}
您可以在此处添加逻辑,以便在它再次尝试异常时进行定制。
答案 1 :(得分:0)
在高级别,您可以使用Observable模式(内置JDK),以便在维护期间通知您的代码。您可以通过生成新线程来重新建立连接。
答案 2 :(得分:0)
使用此构造:
try{
// code to update db
}
catch(MySQLSyntaxErrorException exception){
// handle db exception
}
在你的线程中运行以使用db。