繁体   English   中英

Java ScheduledExecutorService仅执行一次

[英]Java ScheduledExecutorService executes only once

我是Java的新手,正尝试制作一个可定期从Ubidots变量读取一些信息的Android APP。

经过一些在线研究,我设法找到了这种方法。

问题是它只执行一次。 第一次迭代后,它再也不会通过syncTimer。

        Runnable syncTimer = new Runnable() {
        public void run() {
            ubi.execute(0);

            if (!syncComplete)
            {
                System.out.println("Sync not completed. We'll wait");

                while (!syncComplete)
                {
                    //wait.
                }
            }

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    try
                    {
                        syncComplete(tempValue, g_tempVal.toString());
                    }
                    catch (Exception e)
                    {
                        System.err.println("error in executing. It will no longer be run!");
                        e.printStackTrace();
                        throw new RuntimeException(e);
                    }

                }
            });

        }
    };

    ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
    executor.scheduleAtFixedRate(syncTimer, 0, 2, TimeUnit.SECONDS);

这是我的代码,对这个问题有帮助吗? 我全都不知道该在Google上搜索什么以找到解决方法。

我从未使用Java / Android编程,仅使用过其他语言。

syncComplete是AsyncTask之后的布尔集,该AsyncTask连接到Ubidots并检索变量。

   public class ApiUbidots extends AsyncTask<Integer, Void, Void> {
    private final String API_KEY = "key";
    private final String VARIABLE_ID = "var";

    @Override
    protected Void doInBackground(Integer... params) {
        ApiClient apiClient = new ApiClient(API_KEY);
        Variable temperature = apiClient.getVariable(VARIABLE_ID);
        if (params[0] == 0)
        {
            g_tempVal = temperature.getValues()[0].getValue();
            syncComplete = true;
        }
        if (params[0] == 1)
        {
            //implement write function
        }

        return null;
    }

}

如果对syncComplete更改是由另一个线程进行的,则对您的线程不可见。 您需要将syncComplete变量声明为volatile,如下所示:

public volatile boolean syncComplete=false;

使用易失性变量可降低内存一致性错误的风险,因为对易失性变量的任何写操作都会与该变量的后续读取建立先发生后关系。 这意味着对volatile变量的更改始终对其他线程可见。

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

此外,通过在while循环中旋转来进行主动等待也是一种不好的做法。 尝试锁定。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM