timerSchedule не подчиняется установленному таймеру запуска?


У меня есть тестовый файл с тремя строками, каждая строка начинается с отметки времени в секундах. Я читаю этот штамп времени и на его основе планирую новый таймер за каждый прочитанный штамп времени. Почему, когда я запускаю потоки, созданные в методе "processFile", упомянутом ниже, консоль отображает выходные данные трех таймеров одновременно? Я ожидал увидеть выход каждого таймера, разделенный несколькими секундами задержки между ними, как отметку времени каждой из трех строк, которые я читал из файла 2 секунды, 15 секунд и 7 секунд соответственно? когда я запускаю программу, через несколько секунд я получаю ниже" системное время " вывода все сразу без задержки разделяют их, несмотря на то, что временная метка, считываемая из файла, отличается!

Пожалуйста, дайте мне знать, почему это происходит и как это решить.
//this method is being called on a worker thread

    private static void processFile(File dataFile) throws IOException {
    // TODO Auto-generated method stub
    System.out.println(WORKER_THREAD + " started.");
    logfile = new MeasurementFile(dataFile, MeasurementFile.ENCODING_UTF_8);
    System.out.println("Total lines in the file: " + logfile.getTotalLines());
    System.out.println("#Parameters/line: " + logfile.getFileHash().get(logfile.getTotalLines()).getFullParameters().length);
    System.out.println("Time Stamp in Seconds: " + logfile.getFileHash().get(logfile.getTotalLines()).getTimeStampInSec());

    timer = new Timer();
    for (int i = 1; i <= logfile.getTotalLines(); i++) {
        ++currentLine;
        t = new Thread(new threadFile(), "logFile_Thread_" + i);
        t.start();
    }

}

static class threadFile implements Runnable {
    public void run() {
        timer.schedule(new timedTask(), (long) logfile.getFileHash().get(currentLine).getTimeStampInMilli());
    }
}

static class timedTask extends TimerTask {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        long nanoTimer = System.nanoTime();
        //long milliTimer = System.currentTimeMillis();
        System.out.println("systemTime(ns): " + nanoTimer);
    }
}

Вывод :

file processing thread started.
Total lines in the file: 3
#Parameters/line: 9
Time Stamp in Seconds: 7.0
systemTime(ns): 4882255697670
systemTime(ns): 4882255928644
systemTime(ns): 4882255985104
2 2

2 ответа:

Я подозреваю, что цикл for и счетчик внутри него и способ, которым вы создаете экземпляр потока n ew. Я бы сделала это таким образом.

for (int i = 1; i <= logfile.getTotalLines(); i++) {
    t = new Thread(threadFile, "logFile_Thread_" + i);
    t.start();
}

static Runnable threadFile = new Runnable() {

    public void run() {
        // TODO Auto-generated method stub
        ++currentLine;
        timer.schedule(new timedTask(), (long)  
        logfile.getFileHash().get(currentLine).getTimeStampInMilli());
    }
};

Потому что счетчик в for-цикле, получит всегда свое максимальное значение, которое будет применено ко всем Таймерным задачам. другими словами, если у вас есть цикл для 5 итераций, счетчик получит свое максимальное значение в зависимости от того, как счетчик был инициализирован, а затем эти значения счетчика вы используете для анализа конкретных данных из вашего файла, что означает вы всегда получаете значение frm в последней строке, а затем применяете его к timerTask

Я бы решил гонку на currentLine по-другому:

for (int i = 1; i <= logfile.getTotalLines(); i++) {
    t = new Thread(new ThreadFile(i), "logFile_Thread_" + i);
    t.start();
}

Определяя ThreadFile таким образом:

static class ThreadFile implements Runnable {

    private int lineToProcess;

    public ThreadFile( int lineToProcess ) {
         super();
         this.lineToProcess = lineToProcess;
    }

    public void run() {
        timer.schedule(new timedTask(), (long) logfile.getFileHash().get(lineToProcess).getTimeStampInMilli());
    }
}
Таким образом, когда вы создаете runnable, он уже знает, к какой строке обращаться, и нет доступа к общей переменной и нет необходимости в синхронизации.

Все еще может быть какая-то проблема с logfile, так как он тоже общий и не синхронизирован, но если все, что мы делаем, это читаем из него, и чтение не включает в себя обновление его состояния, оно должно быть в порядке.