【问题标题】:Reading data from running thread从正在运行的线程中读取数据
【发布时间】:2013-04-23 18:10:13
【问题描述】:

我知道 Java 线程相关的问题已经被问过很多次了,但我一直无法拼凑出我的问题的答案。我还是线程编程的新手,所以请原谅我的无知。

我不了解与一致性相关的问题,需要根据需要进行适当的同步。问题是关于在当前正在执行的线程中的对象上调用方法。考虑以下示例(这是实验性的,请原谅任何糟糕的设计选择):

  1. 我有一个 JSP 执行一些搜索并返回结果。响应必须在 10 秒内发送给用户(无论搜索是否能够完成)。
  2. JSP 创建一个 ThreadPoolExecutor 并使用 is 来启动一个搜索线程。
  3. JSP 进入休眠状态 2 秒。
  4. JSP 唤醒并检查搜索线程是否有任何结果。搜索 obj 提供了一个 getCurrentResultsCount() 方法,该方法返回一个 int 计数的到目前为止找到的结果。
  5. 步骤 3 和 4 重复 5 次,然后向用户发送响应。搜索线程可以根据需要继续运行(完成后,结果将存储在 servlet 上下文或数据库中,以后可以访问)

我的代码如下所示:

ThreadPoolExecutor pool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
SearchWidget searchWidget = new SearchWidget(searchTerm);
Future<?> searchWidgetFuture = pool.submit(searchWidget);
Thread.sleep(2000);
System.out.println("1. Results so far:" + searchWidget.getCurrentResultsCount());
Thread.sleep(2000);
System.out.println("2. Results so far:" + searchWidget.getCurrentResultsCount());
Thread.sleep(2000);
System.out.println("3. Results so far:" + searchWidget.getCurrentResultsCount());
...
...

以我的方式调用 getCurrentResultsCount() 方法有什么问题或风险吗?它似乎在低容量使用情况下运行良好,但如果容量较高,我是否会冒问题?

非常感谢任何帮助。谢谢!

【问题讨论】:

    标签: java multithreading synchronization threadpool threadpoolexecutor


    【解决方案1】:

    以我的方式调用 getCurrentResultsCount() 方法有什么问题或风险吗?

    不,只要getCurrentResultsCount() 访问某个同步字段就没有问题,因为共享数据正在两个不同的线程中更新和访问。我建议使用AtomicInteger 来存储此类信息。

    它似乎在低音量使用情况下工作正常,但如果音量较高,我是否会冒问题?

    您为更新volatile 字段(AtomicInteger 内部)付出了性能损失,但它相对较小。从表面上看,没有什么可担心的。后台任务数量的增加将大大掩盖 JSP 和线程之间的任何数据共享。

    【讨论】:

    • 太好了,感谢您的更新。获得一些专家意见总是有用的。关于同步的话题,如果只有一个线程更新它并且只有一个线程读取它,是否真的需要同步对变量的访问?假设搜索小部件不断在 ArrayList 中添加结果,并且 JSP 定期检查有多少结果(甚至从搜索小部件中的 ArrayList 获取最新添加的结果),我是否需要担心同步访问 ArrayList? (假设 JSP 代码跟踪上次获取的索引,因此不会从 ArrayList 中删除任何记录)。
    • 如果必须正确更新值,则需要同步。否则你的 JSP 永远看不到正确的值。它不会抛出,但它是不可预测的。就ArrayList 而言,唯一可以在线程之间共享ArrayList 的情况是它没有被更改。如果编写器进行任何更改,可能会导致不同步的读取器抛出异常。
    • 总而言之,担心这些性能问题是过早的优化。您正在编写一个网络应用程序,同步将只占服务器负载的一小部分@Mohammad。
    • 我想我正误入过早的优化,因为我害怕遇到由于我没有线程经验而可能无法解决的线程问题。谢谢。
    猜你喜欢
    • 2012-02-16
    • 2018-03-22
    • 1970-01-01
    • 2021-03-27
    • 2014-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多