简体   繁体   English

如何强制执行Singleton(一个ScheduledExecutorService的全局实例),一次执行一项任务?

[英]How to enforce singleton (one global instance of) ScheduledExecutorService, one task at a time?

I've got an application that needs to request data from the server, sometimes as a one off request, other times it needs to poll at a fixed rate. 我有一个需要从服务器请求数据的应用程序,有时是一次性请求,而其他时候则需要以固定速率轮询。

For the one off requests I just use a thread like so: 对于一个关闭的请求,我只使用如下线程:

    public void request() {
        Thread requestThread = new Thread(this);
        requestThread.start();
    }

These are ok, they execute and then they're done. 这些没问题,先执行,然后完成。

However, for the long polling tasks, I can never seem to have only one of them executing at a time. 但是,对于长时间的轮询任务,我似乎永远无法一次只执行其中之一。

What I want is that the following method: 我想要的是以下方法:

    public void longPoll() {
        try {
            pollingScheduledExecutor.scheduleAtFixedRate(this, 0, 3, TimeUnit.SECONDS);
        } catch (Exception ignored) {
        }
    }

Would only ever be able to exist once, but what's happening now is that when I call it from the first class it begins normally, but it doesn't ever stop after it's call from the second task. 曾经只能存在一次,但是现在发生的是,当我从第一个类调用它时,它通常开始,但是从第二个任务调用后,它永远不会停止。

How to enforce that there's only one global instance of this ScheduledExecutorService ? 如何强制该ScheduledExecutorService只有一个全局实例?

For context, here is the class wherein these methods live: 对于上下文,这是这些方法所在的类:

public abstract class AbstractCommunicationChannel implements Runnable {
    static String SERVER_ADDRESS = "http://0.0.0.0";

    private URL url;
    private JSONObject requestObject;
    private JSONObject responseObject;

    private volatile ScheduledExecutorService pollingScheduledExecutor = Executors.newSingleThreadScheduledExecutor();

    public void longPoll() {
        try {
            pollingScheduledExecutor.scheduleAtFixedRate(this, 0, 3, TimeUnit.SECONDS);
        } catch (Exception ignored) {
        }
    }

    public void request() {
        Thread requestThread = new Thread(this);
        requestThread.start();
    }

    AbstractCommunicationChannel(URL url, JSONObject requestObject) {
        this.url = url;
        this.requestObject = requestObject;
    }

    /**
     * This is the general purpose tool for hitting the server and getting a response back.
     */
    public void run() {
        Log.i("requestObject", requestObject.toString());
        try {
            HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
            httpUrlConnection.setDoOutput(true);
            httpUrlConnection.setRequestMethod("POST");
            httpUrlConnection.setRequestProperty("Content-Type", "application/json; charset=utf-8");

            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(httpUrlConnection.getOutputStream());
            outputStreamWriter.write(requestObject.toString());
            outputStreamWriter.flush();
            outputStreamWriter.close();
            /* * */
            InputStream inputStream = httpUrlConnection.getInputStream();
            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            int result = bufferedInputStream.read();
            while (result != -1) {
                byteArrayOutputStream.write((byte) result);
                result = bufferedInputStream.read();
            }
            responseObject = new JSONObject(byteArrayOutputStream.toString("UTF-8"));
            httpUrlConnection.disconnect();
        } catch (Exception ignored) {
        }
        processResponse(responseObject);
    }

    protected abstract void processResponse(JSONObject responseObject);
}

its again me. 又是我。

If you want only one running polling task, you have to cancel the previous one if already exist. 如果只需要一个正在运行的轮询任务,则必须取消前一个任务(如果已存在)。

Example: 例:

private static final Object lock = new Object();
private static ScheduledFuture<?> currentRunningTask;

    public void longPoll() {

        synchronized (lock) {

            if (currentRunningTask != null) {
                currentRunningTask.cancel(true);
            }

            try {
                currentRunningTask = pollingScheduledExecutor.scheduleAtFixedRate(this, 0, 3, TimeUnit.SECONDS);
            } catch (Exception ignored) {
                ignored.printStackTrace();
            }
        }
    }

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

相关问题 如果上一个未完成,如何不启动ScheduledExecutorService任务 - How not to start ScheduledExecutorService task if previous one is not finished 仅关闭 ScheduledExecutorService 中的一项任务 - shutdown only one task in ScheduledExecutorService 如何在特定时间停止/取消ScheduledExecutorService中的任务? - How to stop/cancel a task in ScheduledExecutorService at particular time? 当一个任务引发异常时,如何获取ScheduledExecutorService来继续执行其他后续任务 - How do i get ScheduledExecutorService to keep executing other subsequent tasks when one task throws an exception 检索使用ScheduledExecutorService计划的任务实例 - Retrieving a task instance scheduled with ScheduledExecutorService 如何保证在EDT上运行ScheduledExecutorService? - How does one guarantee that an ScheduledExecutorService is running on the EDT? 如何在特定时间段内使用 ScheduledExecutorService 运行任务? - How to run a task DURING PARTICULAR PERIOD OF TIME with ScheduledExecutorService? 如何使用 ScheduledExecutorService 每天在特定时间运行某些任务? - How to run certain task every day at a particular time using ScheduledExecutorService? 如何从 ScheduledExecutorService 中删除任务? - How to remove a task from ScheduledExecutorService? 如何使用ScheduledExecutorService重新安排任务? - How to reschedule a task using a ScheduledExecutorService?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM