【问题标题】:Java threads without affecting performance不影响性能的 Java 线程
【发布时间】:2013-10-30 10:19:26
【问题描述】:

长话短说;我编写了一个包含无限循环的程序,其中一个函数连续运行,并且必须尽可能快地运行。

但是,虽然此函数在微秒时间范围内完成,但我需要生成另一个线程,这将花费相当长的时间来运行,但它不能影响前一个线程。

希望这个例子能帮助解释事情:

while (updateGUI == true) { //So, forever until terminated

        final String tableContents = parser.readTable(location, header);
        if (tableContents.length() == 0) {//No table there, nothing to do
        } else {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
                    //updateTable updates a JTable 
                    updateTable(tableContents, TableModel);
                    TableColumnModel tcm = guiTable.getColumnModel();
                }
            });
        }
     ***New thread is needed here!
    }

所以我需要readTable 函数运行无限次,然后我需要启动第二个线程,该线程也将运行无限次,但是它需要毫秒/秒才能完成,因为它必须执行一些文件 I/O 并且可能需要一些时间才能完成。

我尝试过扩展Thread 类,并使用Executors.newCacheThreadPool 尝试生成一个新线程。但是,我所做的任何事情都会导致 readTable 函数变慢,并导致表无法正确更新,因为它无法足够快地读取数据。

我可能需要重新设计此循环的运行方式,或者可能只是启动两个新线程并将无限循环放入其中。

以这种方式设计它的原因是,一旦updateTable 函数运行,它会返回一个用于更新JTable 的字符串,这(据我所知)必须是在 Java 的 Main Dispatch Thread 上完成,因为这是 GUI 表的创建位置。

如果有人有任何建议,我将不胜感激。

谢谢

【问题讨论】:

  • 如果不处理 == 0 的情况,最好使用 if (tableContents.length() != 0) 并删除 else 。
  • 啊,是的,好点。谢谢!

标签: java multithreading swing concurrency jtable


【解决方案1】:

当您更新JTable 时,SwingWorker 会很方便。在这种情况下,一个工作人员可以与另一个工作人员共存,正如 here 所建议的那样。

【讨论】:

  • 谢谢垃圾神。我认为摇摆工人是要走的路。我将回到我的代码并重新编写它。感谢您的意见。
【解决方案2】:

您必须非常小心,以免机器超载。您需要使长时间运行的任务独立于必须快速的线程。您还需要限制一次运行的数量。一开始我会设置一个上限。

另外你的屏幕只能更新这么快,你只能看到屏幕更新这么快。一开始,我会将每秒更新次数限制为 20 次。

顺便说一句,设置优先级仅在您的机器过载时才有帮助。您的目标应该是首先确保它不会超载,然后优先级就无关紧要了。

【讨论】:

  • 谢谢彼得。好点子。我想我需要回去寻找一个更好的地方来处理 GUI 的更新以及线程的产生。
  • 你真的需要生成线程吗?你能只用一个线程来做他们正在做的工作吗?
  • 供参考,SwingWorker limits GUI 更新为 33Hz。
  • @trashgod 好点。电影以 42 Hz(每 ~27 毫秒)闪烁,而您看不到。
  • @Peter Lawrey FlameWar,这是比较 LCD(标准)和 Cinema 24_times per sec 的错误想法,不要比较太慢的单个像素重绘与更换整个区域,这可以通过专业等离子显示器实现(同步)或 CRT(异步,因为像素是从左上角到右下角重绘的,所以会有小的延迟)
【解决方案3】:

很难猜出这里发生了什么,但您说“导致表未正确更新,因为它无法足够快地读取数据”。如果您的意思是代码的正确性受到时序不够快的影响,那么您的代码不是线程安全的,您需要使用适当的同步。

正确性不能依赖于时间,因为线程执行的时间在标准 JVM 上是不确定的。

另外,不要摆弄线程优先级。除非您是并发专家,尝试做一些非常不寻常的事情,否则您不需要这样做,这可能会使事情变得混乱和/或中断。

【讨论】:

  • 谢谢恩诺。本质上,发生的是无限循环从另一个进程生成的内存映射文件中读取。该文件不断变化,因此必须尽快对其进行解析,因为它会不断更新。
  • 您可以使用文件锁。但是像套接字或命名管道这样的东西听起来更好。从本质上讲,您正在从这个过程中获得不想错过的更新,对吧?
【解决方案4】:

因此,如果您希望您的“无限”循环线程具有最高优先级,为什么要将 EDT 的优先级设置为 MAX 以让您成为“最宝贵的”?

               Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
                //updateTable updates a JTable 
                updateTable(tableContents, TableModel);
                TableColumnModel tcm = guiTable.getColumnModel();

在这段代码中,当前线程将与 EDT 或 EDT 产生一个。为什么不在处理whileloop 之前移动那条线?

【讨论】:

  • 在测试期间添加了最大优先级行,因为之后我尝试生成另一个线程。由于其他线程不再存在,因此可以公平地删除它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-25
  • 2018-04-29
  • 1970-01-01
  • 2013-09-06
  • 1970-01-01
相关资源
最近更新 更多