Хорошо, я пытался преобразовать сетевой блокирующий запрос в неблокирующий. Библиотека, которую я использую для сетевого ввода-вывода, предоставляет функции для выполнения асинхронных HTTP-вызовов, но в любом случае, ради экспериментов, я попытался сделать это следующим образом:
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import com.mashape.unirest.request.GetRequest;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class TestExecutorService {
private static final ExecutorService executor = Executors.newSingleThreadExecutor();
static volatile Thread innerThread;
public static void asyncGet (String url) {
executor.execute(new Runnable() {
@Override
public void run() {
innerThread = Thread.currentThread();
GetRequest request = Unirest.get(url);
try {
HttpResponse <String> response = request.asString();
System.out.println(response.getBody());
Unirest.shutdown();
} catch (UnirestException exc) {
exc.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
});
}
}
public class Main {
public static void main(String[] args) {
TestExecutorService.asyncGet("https://stackoverflow.com");
System.out.println("We're already here!");
try {
// Delay so that executor service's thread object could be
// ...assigned to static variable innerThread
Thread.sleep(100);
TestExecutorService.innerThread.join();
} catch (InterruptedException ie) {
ie.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
Я не профессиональный программист и не абсолютный новичок, когда дело доходит до параллелизма, и даже я могу сказать, что этот кусок кода можно улучшить, хотя бы немного (одно из тех ощущений, которые вы испытываете как новичок, когда знаете что то не так, но не уверен что есть). В любом случае, что смущает меня в коде выше, так это то, что программа не завершается. Я не ожидал, что это произойдет. Я прочитал немного о Executors.singleThreadExecutor
, и у меня есть идея, что если внутренний поток по какой-то причине умирает, он создает новый поток и безопасно «переносит» состояние во вновь созданный поток. Я понятия не имею, почему программа не завершается, хотя. Может кто-нибудь дать несколько советов?
Обратите внимание, что приведенный здесь код не будет использоваться в производственных средах. Я написал это только для практики.