2

我有两台linux机器。在一台机器上,我正在使用一个启动可执行文件的线程,另一个内部线程从可执行文件中读取数据并使用可执行文件中的值填充数据库,我正在使用 myBatis 来持久化数据。稍后它会不断检查进程和内部线程是否启动并运行。在另一台机器上,我远程连接了数据库,该数据库每晚持续部署,因此数据库被删除并重新创建。因此,由于在此构建期间数据库表不可用,因此出现异常:

org.apache.ibatis.exceptions.PersistenceException 
### Error updating database.  Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
Table 'updates_table' doesn't exist

被抛出。然后不断检查进程和内部线程的线程被杀死并停止检查。

谁能帮助我如何处理线程不被杀死,一旦数据库可用并运行它应该尝试重新填充表。当数据库不可用时,它应该一直尝试直到数据库可用。

谢谢你。

4

3 回答 3

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)or Executors.newCachedThreadPool()。请注意,这回答了如何让您的线程保持活力。如果要在作业失败时重新提交可运行以重新执行,请将其run方法更改为:

@Override
public void run() {
    try {
        // Do database stuff with obj
    } catch (PeristenceException ex) {
        // Try again
        executor.execute(this);
    }
}

您可以为此添加逻辑以定制何时再次尝试异常。

于 2012-09-07T20:27:48.600 回答
0

在高层次上,您可以使用 Observable 模式(内置于 JDK),以便在维护期间通知您的代码。您可以通过产生一个新线程来重新建立连接。

于 2012-09-07T20:24:46.933 回答
0

使用这个构造:

try{ // code to update db
} catch(MySQLSyntaxErrorException exception){ // handle db exception }

在运行以与数据库一起使用的线程内部。

于 2012-09-07T20:38:18.217 回答