【问题标题】:Raspberry pi with java application high CPU usage具有 Java 应用程序高 CPU 使用率的树莓派
【发布时间】:2018-10-10 16:05:20
【问题描述】:

我在我的树莓派上运行了一个 java 应用程序,但它大部分时间都崩溃了。每当它崩溃时,它通常会从 java 中获得非常高的 CPU 使用率(> 100%)。我的应用程序是如何工作的:我有一个读取标签的 RFID 阅读器,每当读取标签时,就会调用 messageReceived 方法。该方法将读取的标签存储在特定的集合中。然后我创建一个新线程来侦听套接字,当套接字打开并且集合发生更改时,该线程调用一些 javafx 方法来打开新屏幕。但是,当我将应用程序部署到我的树莓派时,它会随机崩溃,并且 java 的 CPU 使用率很高。如果我忘记解释任何事情,请随时提出任何问题。

编辑 1:我的线程类。 编辑 2:我现在的问题是:为什么我的 CPU 使用率这么高,我该如何解决。

public class RFIDThread implements Runnable {
    /**
     * The socket for the connection to the LLRP Reader
     */
    private Socket socket;

    private JSONArray valid_tags;

    private JSONArray found_tags;

    private TagsListController controller;

    private RFIDSet rfidset;

    /**
     * Thread for constant reading of the stream
     * 
      * @param socket
      * @param controller
      * @param tags
     */
    public RFIDThread(Socket socket, TagsListController controller, JSONArray tags, RFIDSet rfidset) {
         this.socket = socket;
         this.controller = controller;
         this.rfidset = rfidset;
         this.found_tags = new JSONArray();
         this.valid_tags = tags;
    }


     /**
      * Runnable for this thread.
      * First get all the found tags from the xml controller
      * Then loop over the rfid set to find any new tags.
      * If there are any, display them.
      */
    @Override
    public void run() {
        CopyOnWriteArrayList<Tag> originalSet = new CopyOnWriteArrayList<>();
        originalSet.addAll(rfidset.getSet());
        boolean started = true;

        if (socket.isConnected()) {
            while (!socket.isClosed()) {
                CopyOnWriteArrayList<Tag> set = new CopyOnWriteArrayList<>();
                set.addAll(rfidset.getSet());
                if(started || !originalSet.equals(set)) {
                    started = false;
                    CopyOnWriteArrayList<String> found_set = new CopyOnWriteArrayList<>();
                    found_set.addAll(controller.found_tags_list.getItems());                                      

                    this.found_tags.clear();
                    this.found_tags.addAll(found_set);


                    for (Tag found_tag : set) {
                        if (found_tags.indexOf(found_tag.getId()) < 0) {
                            Integer index = valid_tags.indexOf(found_tag.getId());
                            if (index >= 0) {
                                Platform.runLater(() -> controller.showValid(found_tag.getId()));
                            } else {
                                Platform.runLater(() -> controller.showError(found_tag.getId()));
                            }

                            found_tags.add(found_tag.getId());

                            pause(5000);
                        }
                    }

                    originalSet = set;

                    pause(5000);
                }
            }
        }
    }


    /**
     * Close the socket
     */
    public void shutdown() {
       try {
           this.socket.close();
       } catch (IOException e) {
           e.printStackTrace();
       }
    }

    private void pause(long ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

【问题讨论】:

  • 你有什么问题?
  • 这取决于您的代码。发布您的代码。
  • 我不知道为什么我的 CPU 使用率这么高,所以我想寻求帮助。@Turing85
  • 你试过分析它吗?
  • 如果你的树莓派在 CPU 使用率高的时候会自行重启,那么你的电源可能是微不足道的。寻找更好的电源 - 不要只使用手机充电器。

标签: java multithreading javafx


【解决方案1】:

尝试将pause(5000); 移到if (started || !originalSet.equals(set)) { 语句之外。

高 cpu 使用率通常是一个没有暂停或 I/O 或等待内容的紧密循环。在您的情况下,无论何时originalSet.equals(set) 您都不会暂停。

您可能更喜欢只使用:

                if (started || !originalSet.equals(set)) {
                    // ...
                } else {
                    pause(0);
                }

或类似的。

【讨论】:

    猜你喜欢
    • 2017-12-23
    • 1970-01-01
    • 2022-12-05
    • 1970-01-01
    • 2021-03-06
    • 1970-01-01
    • 1970-01-01
    • 2016-10-25
    • 1970-01-01
    相关资源
    最近更新 更多