如何执行单例(一个全局实例)ScheduledExecutorService,一次执行一项任务?
How to enforce singleton (one global instance of) ScheduledExecutorService, one task at a time?
我有一个应用程序需要从服务器请求数据,有时作为一次性请求,有时它需要以固定速率轮询。
对于一次性请求,我只使用像这样的线程:
public void request() {
Thread requestThread = new Thread(this);
requestThread.start();
}
这些都可以,它们执行然后就完成了。
然而,对于长轮询任务,我似乎永远不能一次只执行其中一个。
我想要的是下面的方法:
public void longPoll() {
try {
pollingScheduledExecutor.scheduleAtFixedRate(this, 0, 3, TimeUnit.SECONDS);
} catch (Exception ignored) {
}
}
只能存在一次,但现在发生的情况是,当我从第一个 class 调用它时它正常开始,但在从第二个任务调用后它永远不会停止.
如何强制只有一个全局实例 ScheduledExecutorService
?
对于上下文,这里是 class 这些方法所在的位置:
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);
}
又是我
如果您只想要一个 运行 轮询任务,则必须取消前一个(如果已经存在)。
示例:
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();
}
}
}
我有一个应用程序需要从服务器请求数据,有时作为一次性请求,有时它需要以固定速率轮询。
对于一次性请求,我只使用像这样的线程:
public void request() {
Thread requestThread = new Thread(this);
requestThread.start();
}
这些都可以,它们执行然后就完成了。
然而,对于长轮询任务,我似乎永远不能一次只执行其中一个。
我想要的是下面的方法:
public void longPoll() {
try {
pollingScheduledExecutor.scheduleAtFixedRate(this, 0, 3, TimeUnit.SECONDS);
} catch (Exception ignored) {
}
}
只能存在一次,但现在发生的情况是,当我从第一个 class 调用它时它正常开始,但在从第二个任务调用后它永远不会停止.
如何强制只有一个全局实例 ScheduledExecutorService
?
对于上下文,这里是 class 这些方法所在的位置:
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);
}
又是我
如果您只想要一个 运行 轮询任务,则必须取消前一个(如果已经存在)。
示例:
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();
}
}
}