【问题标题】:How to enforce singleton (one global instance of) ScheduledExecutorService, one task at a time?如何强制执行单例(一个全局实例)ScheduledExecutorService,一次一项任务?
【发布时间】:2019-06-20 21:24:07
【问题描述】:

我有一个应用程序需要从服务器请求数据,有时作为一次性请求,有时它需要以固定速率轮询。

对于一次性请求,我只使用这样的线程:

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

这些没关系,它们执行然后就完成了。

但是,对于长轮询任务,我似乎永远不可能一次只执行其中一个。

我想要的是以下方法:

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

只能存在一次,但现在发生的情况是,当我从第一个类调用它时,它正常开始,但在从第二个任务调用它后它永远不会停止。

如何强制这个ScheduledExecutorService 的全局实例只有一个?

对于上下文,这里是这些方法所在的类:

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);
}

【问题讨论】:

标签: java multithreading scheduled-tasks threadpool


【解决方案1】:

又是我。

如果您只想要一个正在运行的轮询任务,则必须取消前一个(如果已经存在)。

例子:

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();
            }
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    • 1970-01-01
    • 2018-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多