【问题标题】:Update form real-time when data is concurrently updated in Java在 Java 中同时更新数据时实时更新表单
【发布时间】:2016-05-08 23:28:26
【问题描述】:

假设我有一些类似于以下的数据存储在一个数组(2D)中。我允许多个用户同时更新它,并且我想在表单上实时查看它,或者我可以这样做以查看实时更新。

1   2   3   4   5   
6   7   8   9   10  
11  12  13  14  15  
16  17  18  19  20  
21  22  23  24  25  
26  27  28  29  30  
31  32  33  34  35 

谁能帮我用Java完成上述任务?如果有其他语言(如 Python)的好方法,我也将不胜感激。

【问题讨论】:

  • 您的数据是否存储在数据库中?它是一个网络应用程序吗?您使用哪些库来显示这些信息?
  • current 我将它保存在一个文本文件中,但如果它能让我的生活更轻松,我可以将它移动到数据库中。请提出最佳选择。谢谢

标签: java concurrency real-time live


【解决方案1】:

您必须在方法或块上使用“同步”语句来保存用户更改。它通过只允许一个用户执行整个同步块直到完成来控制对代码的访问。

这是一个包含一些示例的文档链接。

https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

【讨论】:

    【解决方案2】:

    我假设:

    • 您可以接受以几十毫秒为单位的预定义值的刷新率。
    • 您可以接受用户同时相互覆盖并丢失更新。
    • 您并没有兴趣从最终使用的解决方案中榨取每一盎司的性能。
    • 在不了解这些技术如何在内部工作并修改它们以适应新要求的情况下,您不会将此处提供的技术用于不同的用例。

    话虽如此,您可以简单地使用int 元素的单个共享数组和单个共享AtomicLong 跟踪其修订。然后,您可以允许每个并发用户对数组进行更新,只需确保 AtomicLong 在用户每次更新时递增。

    您可以让 UI 线程定期检查共享数据,方法是先读取 AtomicLong,然后读取数组内容 - 周期的长度将取决于您要保持的帧速率,但我会认为 30 毫秒应该足够了。

    由于AtomicLong 的写入和读取之间存在happens-before 边缘,您可以确保看到线程内容正在更新。请注意,如果您想使用 longs 的数组,您需要确保对每个数组元素的写入都是原子的。

    这里用一些虚拟代码简单说明原理:

    import java.util.Arrays;
    import java.util.Random;
    import java.util.concurrent.atomic.AtomicLong;
    
    public class Playground {
    
       private static AtomicLong REVISION = new AtomicLong(0);
       private static int[] ARR = new int[10];
    
       private static final int NUM_THREADS = 100;
       private static final int NUM_UPDATES_PER_THREAD = 100;
    
       public static void main(String[] args) {
          new Thread(() -> {
             int totalRevs = NUM_THREADS * NUM_UPDATES_PER_THREAD;
             while (REVISION.get() < totalRevs) {
                System.out.println(Arrays.toString(ARR));
                try {
                   Thread.sleep(50);
                } catch (Exception e) {}
             }
          }).start();
          for (int i = 0; i < NUM_THREADS; ++i) {
             final int iCopy = i;
             new Thread(() -> {
                for (int j = 0; j < NUM_UPDATES_PER_THREAD; ++j) {
                   Random rnd = new Random();
                   int sleepTime = rnd.nextInt(100);
                   try {
                      Thread.sleep(sleepTime);
                   } catch (Exception e) {}
                   int index = rnd.nextInt(10);
                   int value = rnd.nextInt();
                   ARR[index] = value;
                   REVISION.incrementAndGet();
                }
             }).start();
          }
       }
    }
    

    【讨论】:

    • 感谢您的帮助,但我关心的是如何在表单上呈现更新输出?问候
    • @vchar 啊哈...好吧,我建议在您的问题中更明确地重申这一点,并通过相应地标记它来表明您的意图。现在你的问题看起来就像我试图回答的那样:)我猜想解决你的问题你会比解决它的 UI 一半更难解决它的并发问题,但另一方面你会询问更广泛的受众是否关心以表单形式呈现数组。
    猜你喜欢
    • 1970-01-01
    • 2020-07-20
    • 2014-01-16
    • 2021-03-08
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 2017-08-06
    • 2014-09-15
    相关资源
    最近更新 更多