Я запустил свою программу, которая имеет два цикла:
for(int i=0;i<100;i++)
String[] articles = getArticles(i);
for(int j=0;j<articles.length;j++)
process(articles[j]);
Могу ли я изменить запущенную программу, чтобы она остановилась при я = 1? Если, как это сделать?
Программа займет несколько дней, и я хочу остановиться, но я должен знать, где она была остановлена, поэтому в следующий раз я смогу ее возобновить.
Это возможно (много вещей). Но это может быть очень и очень сложно - если вы не умеете смотреть на байт-код Java и не знаете внутренних систем, я бы не пробовал.
Предполагая, что вы работаете под Linux, вы можете приостановить и перезапустить процессы с помощью kill -STOP <pid>
и kill -CONT <pid>
. Вы также можете взять трассировку стека запущенного java-процесса через jstack и посмотреть на выполняемые потоки и декомпилированный код.
К сожалению, вы не сможете остановить запущенную программу в предсказуемом месте, если не включен отладчик.
Остановите свою программу, измените код и запустите его снова.
Нет простого способа сделать это, но с небольшой дополнительной работой можно сделать. Один из способов - вывести последнюю успешную итерацию в постоянное хранилище (например, файл), а затем прочитать файл, если он существует, чтобы узнать, с чего начать. В приведенном ниже примере показан один из способов сделать это:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
public class Test
{
public static void main(String[] args)
{
int start;
// Try to get the last successful run
File file = new File(System.getenv("HOME"), ".myprog");
if(file.exists()) {
try(BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line = reader.readLine();
if(line == null) {
throw new NumberFormatException("Empty file, no number");
}
start = Integer.parseInt(line);
} catch(IOException | NumberFormatException ex) {
System.err.println("Unable to read progress: " + ex.getMessage());
System.err.println("Starting from the beginning");
start = 0;
}
} else {
start = 0;
}
// ... Your declarations go here
for(int i = start; i < 100; i++) {
String[] articles = getArticles(i);
for(int j=0;j<articles.length;j++) {
process(articles[i]);
}
// Record last successful run (this reopens the file every time)
try(PrintWriter writer = new PrintWriter(file)) {
writer.println(i);
} catch(IOException ex) {
System.err.println("Unable to record progress: " + ex.getMessage());
}
}
}
}
Обратите внимание, что я запускаю машину Linux, поэтому я назвал свой файл ~/.myprog
. Вы можете изменить это.
Вы можете это сделать
static boolean stopLoop = false;
static int[] runLoop(int i, int j) {
for(;i<100;i++) {
if(stopLoop) return new int[i, j];
String[] articles = getArticles(i);
for(;j<articles.length;j++) {
process(articles[i]);
}
j = 0;
}
}
(Вероятно, вы хотели написать process(articles[j]);
в своем внутреннем цикле.)
Вы можете сохранить последнее значение i
и j
в файл после обработки каждой статьи, тогда вы можете завершить свою программу в любое время, когда захотите, и в следующий раз просто прочитайте значения i
и j
из вашего файла, и вам не нужно обрабатывать их снова.
Или установите 100 процессов для каждого прогона программы или процесс в течение 20 минут, есть так много возможностей.