【问题标题】:Java single worker thread for SQL update statements用于 SQL 更新语句的 Java 单工作线程
【发布时间】:2012-10-20 04:21:47
【问题描述】:

我正在开发一个基于 Java 的服务器,其中我将拥有多个线程(每个连接的用户一个线程 + 一些额外的线程)。将涉及一些数据库连接,所以我在想每次服务器对数据库进行 SELECT 查询时,它都会为此启动一个新线程,以防止当前线程阻塞。我打算为此使用连接池,我想我知道该怎么做。 (我已经查看了C3P0)但是,也会涉及很多 UPDATE 语句,但是直接运行这些语句并不重要,这里有延迟也没关系。由于可能有很多 UPDATE 语句,我正在考虑为所有 UPDATE 语句设置一个工作线程。在我看来,这将具有能够重用PreparedStatement-objects 的优势

问题: 我怎样才能从其他线程告诉 UPDATE-worker 线程运行一些语句?我知道多线程以及如何使用同步块使线程相互“对话”,但是涉及到数据库时,它突然感觉更复杂了。我读过准备好的语句和连接不应该在线程之间共享。

我现在关于如何解决它的想法:(感觉不是一个好的解决方案)

使用自定义类的LinkedBlockingQueue(或另一种队列),其中包含有关要调用哪种 UPDATE 语句以及要发送哪些参数的信息。然后工作线程将在收到通知时从该队列中读取(当将某些内容添加到队列中时)并在那里运行适当的方法,该方法将使用适当的准备好的语句,设置参数并调用它。

编辑:我认为自己使用这种方法的一个不好的想法是参数可能是整数、字符串、双精度或其他。如何将它们存储在自定义类中?将它们全部存储为字符串感觉不好。

我是在正确的轨道上还是有更好的方法来解决这个问题?

【问题讨论】:

  • 您不需要通知过程 - 只需调用 queue.poll(timeout, timeunit) 就会阻塞,直到将某些内容添加到队列中。
  • @assylias 谢谢,这样会更容易一些。通过使用队列来执行此操作,您认为我走在正确的轨道上吗?
  • 嗯...忽略我之前的评论:您可以致电queue.take(),它会一直阻塞,直到有东西在队列中。您的方法是有道理的 - 您有一个线程调用 queue.take 来等待查询被放入队列,执行它并返回到 queue.take()
  • @assylias 你知道存储队列中每个项目的参数的更好方法吗?我能想到的就是将它们存储为字符串或对象(然后检查它是否是整数、双精度、字符串...)

标签: java multithreading jdbc queue connection-pooling


【解决方案1】:

不需要显式阻塞队列。你可以有一个工作线程和一个由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));

单线程执行器只是一个在队列中等待并按顺序执行提交的任务的工作线程。无需其他显式管理。

【讨论】:

  • 像魅力一样工作!虽然我创建了几个不同的 ThreadTask 类,但每种 UPDATE 语句一个类。
  • @SimonForsberg 使用组合而不是继承!
猜你喜欢
  • 1970-01-01
  • 2022-06-11
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 2013-02-11
  • 1970-01-01
  • 2015-07-16
  • 1970-01-01
相关资源
最近更新 更多