Я пытаюсь получить HTTP-коды с веб-сайтов. Когда я разбираю сайты без потоков, один за другим, все в порядке. Но если я использую потоки, иногда получаю
java.sql.SQLException: After end of result set
в
URL url = new URL(rset.getString("url"));
Я думаю, что проблема в тайм-аутах, и пытался разорвать цикл, если таймаут> то я хочу.
if (connection.getConnectTimeout()>10)
{
System.out.println("timeout");
break;
}
Но похоже, что это никогда не срабатывает. Что я делаю неправильно? Спасибо. Полная часть кода проблемы приведена ниже.
static class JThread extends Thread {
JThread(String name){
super(name);
}
public void run() {
try {
while (rset.next()) {
System.out.println("hello");
URL url = new URL(rset.getString("url"));
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
if (connection.getConnectTimeout()>10)
{
System.out.println("timeout");
break;
}
//Thread.sleep(1000);
int code = connection.getResponseCode();
System.out.println(code);
}
} catch (SQLException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Thread stopped");
}
}
I am trying to get HTTP codes from websites. When I parse sites without threads, one-by-one, everything is fine. But if I use threads, sometimes I receive
java.sql.SQLException: After end of result set
atURL url = new URL(rset.getString("url"));
Это не имеет ничего общего с тайм-аутом HTTP. Вы получаете исключение, потому что вы пытаетесь получить столбец «url» из строки базы данных после того, как вы уже прочитали все результаты (и больше нет результатов для чтения).
Вы говорите, что это происходит только тогда, когда вы используете несколько потоков. Похоже, что поток входит в цикл while (верно rset.next()
). Затем другой поток вызывает rset.next()
(проходя мимо конца набора результатов), получает ложь и не входит в цикл. Затем первый поток пытается получить URL-адрес, но вы уже пропустили последний результат.
Вам следует синхронизировать доступ к ResultSet (или любому объекту), если он используется несколькими потоками, но, вероятно, было бы лучше просто не использовать ResultSet между потоками. Лучшим способом разделения работы было бы, чтобы один поток получал URL-адреса из базы данных, а 1 или несколько потоков выполняли HTTP-соединение (например, пул потоков, новый поток для каждого URL-адреса и т. д.).
Вам необходимо синхронизировать вызовы с ResultSet.next()
и заранее проверить, не исчерпался ли он.
Теперь у вас есть два потока, вызывающих его одновременно, и первый получает последнюю строку, а следующий пытается получить строку, когда набор результатов уже исчерпан.