同时使用超时和信号量进行线程阻塞
Using both timeout and semaphore for Thread blocking
我有一个 运行 的方法可以连接到服务器,当服务器出现故障时,它会一直等到它收到服务器再次启动的消息。但是,整个方法应该有一个超时时间,如果超过时间,方法应该中断并且 return 错误日志代替。
private Semaphore sem = new Semaphore(0);
private TimeUnit unit = TimeUnit.MILLISECONDS;
public String some_method(Object params, long timeout, TimeUnit unit) {
long time = 0;
while(time < timeout) { // not sure about timeout method
try {
//some task that is prone to ServerConnectException
return; // returns value and exits
} catch(ServerConnectException ex) {
sem.acquire();
} catch(InterruptedException uhoh) {
System.out.println("uhoh, thread interrupted");
}
// increment time somehow
}
sem.release();
return null; // a message of task incompletion
}
- 我正在考虑 运行 设置一个包含信号量的线程,如果出现服务器故障问题,该线程会阻塞线程,但我似乎无法组织线程,使其包含信号量但由方法本身包含。
问题:
- 但是,该方法已经在一个巨大的 class 中并且为该方法创建单独的线程会弄乱整个调用层次结构以及整个 API,所以我不想那样做。我需要一些 运行s 和 some_method 的进程,并根据需要在其进程上放置锁定和释放,并设置超时。我应该怎么想?其他一些并发包装器,如执行器?
谢谢!
信号量似乎不是在这里使用的正确并发原语,因为您实际上不需要锁定实用程序,而是帮助您协调线程间通信的实用程序。
如果您需要传递值流,通常会使用阻塞队列,但如果您需要传递单个值,CountDownLatch 和变量就可以了。例如(未经测试):
public String requestWithRetry(final Object params, long timeout, TimeUnit unit) throws InterruptedException {
String[] result = new String[1];
CountDownLatch latch = new CountDownLatch(1);
Thread t = new Thread(new Runnable() {
public void run() {
while (true) {
try {
result[0] = request(params);
latch.countDown();
return;
}
catch(OtherException oe) {
// ignore and retry
}
catch(InterruptedException ie) {
// task was cancelled; terminate thread
return;
}
}
}
});
t.start();
try {
if (!latch.await(timeout, unit)) {
t.interrupt(); // cancel the background task if timed out
}
// note that this returns null if timed out
return result[0];
}
catch(InterruptedException ie) {
t.interrupt(); // cancel the background task
throw ie;
}
}
private String request(Object params) throws OtherException, InterruptedException {
// should handle interruption to cancel this operation
return null;
}
我有一个 运行 的方法可以连接到服务器,当服务器出现故障时,它会一直等到它收到服务器再次启动的消息。但是,整个方法应该有一个超时时间,如果超过时间,方法应该中断并且 return 错误日志代替。
private Semaphore sem = new Semaphore(0);
private TimeUnit unit = TimeUnit.MILLISECONDS;
public String some_method(Object params, long timeout, TimeUnit unit) {
long time = 0;
while(time < timeout) { // not sure about timeout method
try {
//some task that is prone to ServerConnectException
return; // returns value and exits
} catch(ServerConnectException ex) {
sem.acquire();
} catch(InterruptedException uhoh) {
System.out.println("uhoh, thread interrupted");
}
// increment time somehow
}
sem.release();
return null; // a message of task incompletion
}
- 我正在考虑 运行 设置一个包含信号量的线程,如果出现服务器故障问题,该线程会阻塞线程,但我似乎无法组织线程,使其包含信号量但由方法本身包含。
问题: - 但是,该方法已经在一个巨大的 class 中并且为该方法创建单独的线程会弄乱整个调用层次结构以及整个 API,所以我不想那样做。我需要一些 运行s 和 some_method 的进程,并根据需要在其进程上放置锁定和释放,并设置超时。我应该怎么想?其他一些并发包装器,如执行器?
谢谢!
信号量似乎不是在这里使用的正确并发原语,因为您实际上不需要锁定实用程序,而是帮助您协调线程间通信的实用程序。
如果您需要传递值流,通常会使用阻塞队列,但如果您需要传递单个值,CountDownLatch 和变量就可以了。例如(未经测试):
public String requestWithRetry(final Object params, long timeout, TimeUnit unit) throws InterruptedException {
String[] result = new String[1];
CountDownLatch latch = new CountDownLatch(1);
Thread t = new Thread(new Runnable() {
public void run() {
while (true) {
try {
result[0] = request(params);
latch.countDown();
return;
}
catch(OtherException oe) {
// ignore and retry
}
catch(InterruptedException ie) {
// task was cancelled; terminate thread
return;
}
}
}
});
t.start();
try {
if (!latch.await(timeout, unit)) {
t.interrupt(); // cancel the background task if timed out
}
// note that this returns null if timed out
return result[0];
}
catch(InterruptedException ie) {
t.interrupt(); // cancel the background task
throw ie;
}
}
private String request(Object params) throws OtherException, InterruptedException {
// should handle interruption to cancel this operation
return null;
}