如何在Java中插入数据库时​​核心停止线程?

时间:2015-12-09 12:07:58

标签: java multithreading hsqldb

这个问题仍然存在this问题。

我正在尝试停止将行插入dabase的线程,但我总是遇到异常

这部分代码显示了我的线程的逻辑

public void run() {
        String number = "";
        try {
            while (!Thread.currentThread().isInterrupted()) {
                number = generateNumber();
                database.insertOrUpdateRow(number);
            }
        } catch (SQLException ex) {
            LOGGER.error("exception while inserting number " + number + " " + ex.getMessage());
        }
    }

我已经搜索了如何正确停止线程,并发现我应该标记该线程已停止。 所以,这就是我得到的

public boolean stop() {
        try {
            Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
            for (Thread t : threadSet) {
                if (t != null) {
                    if (t.getName().contains("generate")) {
                        t.interrupt();
                        LOGGER.info(t.getName()+" is stopped");
                    }
                }
            }
        } catch (Exception e) {
            LOGGER.error("Exception when call stop: " + e.toString());
        }
        return true;
    }

我的堆栈跟踪

[INFO] [qtp1804418913-32] INFO se.homework.hwbs.tasks.un.server.NumberQtyService
Impl - generate37 is stopped
[INFO] [generate37] ERROR se.homework.hwbs.tasks.un.server.threads.InsertRowThre
ad - exception while inserting number 34587 transaction rollback: serialization
failure
[INFO] [qtp1804418913-33] ERROR se.homework.hwbs.tasks.un.server.database.Databa
se - error select cnt by numberjava.sql.SQLTransactionRollbackException: transac
tion rollback: serialization failure
[INFO] [qtp1804418913-34] ERROR se.homework.hwbs.tasks.un.server.database.Databa
se - error select cnt by numberjava.sql.SQLTransactionRollbackException: transac
tion rollback: serialization failure

线程停止,一切正常,但这种例外让我感觉很糟糕。他们为什么会这样?当我以正确的方式使用数据库时如何停止线程? 数据库是HsqlDB。

2 个答案:

答案 0 :(得分:1)

您可以考虑在插入线程中使用可以直接控制的停止变量,而不是枚举线程并按名称选择一个。

考虑一下这个GeneratorThread:

public class GeneratorThread  extends Thread {

    protected static volatile boolean stop;

    public static void stopExecution() {
        stop = true;
    }

    public GeneratorThread() {
        stop = false;
    }

    public void run() {
        String number = "";
        try {
            while (!stop) {
                number = generateNumber();
                database.insertOrUpdateRow(number);
            }
        } catch (SQLException ex) {
            //Any SQLException will terminate your thread. Is this wanted?!
            LOGGER.error("exception while inserting number " + number + " " + ex.getMessage());
        }
    }
}

你可以通过调用GeneratorThread.stopExecution()来阻止这种情况,GeneratorThread将标志设置为false,导致当前号码成为最后插入的数字。

因为这意味着您的应用程序中只会有一个 while (!stop) { String number = ""; try { number = generateNumber(); database.insertOrUpdateRow(number); } catch (SQLException ex) { LOGGER.error("exception while inserting number " + number + " " + ex.getMessage()); } }

同样,你可能会重新考虑你的同时和尝试捕捉位置。该线程将以任何SQLException结束。如果你想保持线程运行,即使有(临时?)错误,你可能想要

{{1}}

答案 1 :(得分:0)

我结合了@Jan和@Fildor的想法。

所以,这就是我得到的

public class GeneratingThread extends Thread {

private final Logger LOGGER = LoggerFactory.getLogger(InsertRowThread.class);
private final Database database;
private boolean stop = false;

public GeneratingThread(Database database) {
    this.database = database;
}

@Override
public void run() {
    String number = "";
    try {
        while (!stop) {
            number = generateNumber();
            database.insertOrUpdateRow(number);
        }
    } catch (SQLException ex) {
        LOGGER.error("exception while inserting number " + number + " " + ex.getMessage());
    }
}

public void stopThread() {
    this.stop = true;
}

private String generateNumber() {
    int number = ThreadLocalRandom.current().nextInt(0, 100000);
    String sb = Integer.toString(number);
    while (sb.length() < 5) {
        sb = "0" + sb;
    }
    return sb;
}
}

这是我开始的话题

private final List<GeneratingThread> generatingThreads = new ArrayList<>();
GeneratingThread thread = new GeneratingThread(db);
thread.start();
generatingThreads.add(thread);

然后停止

for (GeneratingThread gt : generatingThreads) {
        if (gt != null) {
            gt.stopThread();
            LOGGER.info("Thread is stopped");
        }
    }

对我来说很完美。谢谢你的讨论!