我正在开发一个基于Java的服务器,其中我将有多个线程(每个连接的用户一个线程+一些额外的线程)。将会涉及到一些数据库连接,所以我想每次服务器对数据库进行SELECT查询时,它都会为此启动一个新线程,以防止当前线程阻塞。我计划为此使用连接池,并且我想我知道该怎么做。 (我已经研究过 C3P0 )但是,还会涉及很多 UPDATE 语句,但直接运行这些语句并不重要,这里有延迟是可以的。由于可能有很多 UPDATE 语句,我正在考虑为所有 UPDATE 语句使用一个工作线程。在我看来,这将具有能够重用 PreparedStatement
-objects
问题: 我如何从其他线程告诉 UPDATE-worker 线程运行一些语句?我了解多线程以及如何使用同步块(synchronized block)使线程彼此“对话”,但是涉及到数据库,它突然感觉更加复杂。我读到准备好的语句和连接不应在线程之间共享。
我现在关于如何解决它的想法:(感觉不是一个好的解决方案)
使用自定义类的LinkedBlockingQueue
(或另一种队列),其中包含有关要调用哪种类型的 UPDATE 语句以及要发送哪些参数的信息。然后,工作线程在收到通知时将从该队列中读取数据(当将某些内容添加到队列中时),并且它将运行适当的方法,该方法将使用适当的准备好的语句,设置参数并调用它。
编辑:我认为自己使用这种方法的一个不好的想法是参数可能是整数、字符串、 double 或其他。如何将它们存储在自定义类中?将它们全部存储为字符串感觉不太好。
我走在正确的轨道上还是有更好的方法来解决这个问题?
最佳答案
不需要显式的阻塞队列。您可以拥有一个由 ExecutorService
封装的工作线程和工作队列。 。至于值,您可以使用泛型:
class ThreadTask<T> implements Runnable {
private T value;
public ThreadTask(T value) {
this.value = value;
}
public void run() {
// update based on value
}
}
...
ExecutorService exec = Executors.newSingleThreadExecutor();
exec.submit(new ThreadTask<String>("asdf"));
exec.submit(new ThreadTask<Integer>(1));
单线程执行器只是一个等待队列并按顺序执行提交任务的工作线程。无需其他显式管理。
关于用于 SQL 更新语句的 Java 单工作线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13145588/