Я узнаю о Фазере.При этом я столкнулся с проблемой.Ниже приведен код, который у меня есть,
public class RunnableTask implements Runnable {
private Phaser phaser;
public RunnableTask(Phaser phaser) {
this.phaser = phaser;
this.phaser.register(); // Question
}
@Override
public void run() {
// this.phaser.register(); // Question
print("After register");
for (int i = 0; i < 2; i++) {
sleep();
print("Before await" + i + ":");
this.phaser.arriveAndAwaitAdvance();
print("After advance" + i + ":");
}
}
private void sleep() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void print(String msg) {
System.out.println(String.format("%s: %s, time=%s, registered=%s, arrived=%s, unarrived=%s, phase=%s.", msg,
Thread.currentThread().getName(), LocalTime.now(), this.phaser.getRegisteredParties(),
this.phaser.getArrivedParties(), this.phaser.getUnarrivedParties(), this.phaser.getPhase()));
}
}
Пример теста для вышеупомянутого
public class TestPhaser {
public static void main(String[] args) {
Phaser phaser = new Phaser();
RunnableTask task = new RunnableTask(phaser);
Thread t1 = new Thread(task, "t1");
Thread t2 = new Thread(task, "t2");
Thread t3 = new Thread(task, "t3");
t1.start();
t2.start();
t3.start();
}
}
После выполнения вышеуказанной программы вывод:
Послерегистр: t3, время = 22: 01: 26.636, зарегистрировано = 1, прибыло = 0, не получено = 1, фаза = 0.
После регистра: t2, время = 22: 01: 26.636, зарегистрировано = 1, прибыл = 0, необработанный = 1, фаза = 0.
После регистра: t1, время = 22: 01: 26.636, зарегистрирован = 1, прибыл = 0, необработанный = 1, фаза = 0.
Перед ожиданием 0 :: t3, время = 22: 01: 28.728, зарегистрировано = 1, прибыло = 0, не получено = 1, фаза = 0.
Перед ожиданием 0 :: t2, время =22: 01: 28.728, зарегистрировано = 1, прибыло = 0, необработано = 1, фаза = 0.
До ожидания 0 :: t1, время = 22: 01: 28.728, зарегистрировано = 1, прибыло = 0, unarrived = 1, phase = 0.
После продвижения 0 :: t1, time = 22: 01: 28.728, зарегистрирован = 1, прибыл = 0, unarrived = 1, phase = 3.
После опережения 0 :: t2, время = 22: 01: 28.728, зарегистрировано = 1, прибыло = 0, не получено = 1, фаза = 3.
После опережения 0 :: t3, время = 22:01: 28,729, регистрstered = 1, прибыл = 0, unarrived = 1, фаза = 3.
До ожидания 1 :: t2, время = 22: 01: 30.730, зарегистрирован = 1, прибыл = 0, unarrived = 1, фаза= 3.
Перед ожиданием 1 :: t3, время = 22: 01: 30.730, зарегистрировано = 1, прибыло = 0, не получено = 1, фаза = 3.
После продвижения 1:: t2, время = 22: 01: 30.730, зарегистрировано = 1, прибыло = 0, не получено = 1, фаза = 4.
После продвижения 1 :: t3, время = 22: 01: 30.732, зарегистрировано =1, прибыл = 0, необработанный = 1, фаза = 5.
До ожидания 1 :: t1, время = 22: 01: 30.730, зарегистрирован = 1, прибыл = 0, необработанный = 1, фаза = 3.
После продвижения 1 :: t1, время = 22: 01: 30.732, зарегистрировано = 1, прибыло = 0, необновлено = 1, фаза = 6.
Вы можете видетьздесь много несоответствий.Потоки не продвигаются в последовательности.Кроме того, есть несколько пропущенных или не последовательных фаз.
Когда я переместил строку кода this.phaser.register () из конструктора в начало метода run, вывод будет:
После регистра: t1, time =22: 10: 58.230, зарегистрировано = 3, прибыло = 0, необновлено = 3, фаза = 0.
После регистра: t3, время = 22: 10: 58.230, зарегистрировано = 3, прибыло = 0, необнаружено= 3, фаза = 0.
После регистра: t2, время = 22: 10: 58.230, зарегистрировано = 3, прибыло = 0, не получено = 3, фаза = 0.
До ожидания0 :: t2, время = 22: 11: 00.314, зарегистрировано = 3, прибыло = 0, не получено = 3, фаза = 0.
До ожидания 0 :: t1, время = 22: 11: 00.314,зарегистрировано = 3, прибыло = 0, необработанное = 3, фаза = 0.
До того, как ожидать 0 :: t3, время = 22: 11: 00.314, зарегистрировано = 3, прибыло = 0, необработанное = 3, фаза= 0.
После аванса 0 :: t2, время = 22: 11: 00.315, зарегистрировано = 3, прибыл = 0, не получено = 3, фаза = 1.
После аванса 0:: t3, время = 22: 11: 00.315, зарегистрировано = 3, прибыло = 0, необновлено = 3, фаза = 1.
После продвижения 0 :: t1, время = 22: 11: 00.315, зарегистрировано =3,прибыл = 0, необработанный = 3, фаза = 1.
До того, как ждать 1 :: t1, время = 22: 11: 02.319, зарегистрирован = 3, прибыл = 0, необработанный = 3, фаза = 1.
Перед ожиданием 1 :: t2, время = 22: 11: 02.319, зарегистрировано = 3, прибыло = 0, не получено = 3, фаза = 1.
Перед ожиданием 1 :: t3, время= 22: 11: 02.319, зарегистрировано = 3, прибыло = 0, необновлено = 3, фаза = 1.
После продвижения 1 :: t3, время = 22: 11: 02.320, зарегистрировано = 3, прибыло =0, необработанный = 3, фаза = 2.
После продвижения 1 :: t2, время = 22: 11: 02.320, зарегистрирован = 3, прибыл = 0, необработанный = 3, фаза = 2.
После продвижения 1 :: t1, время = 22: 11: 02.321, зарегистрировано = 3, прибыло = 0, не получено = 3, фаза = 2.
Это выглядит намного лучше, чем потокивыполнение и этапы в последовательности.
Вот мои вопросы:
1) Почему существует много расхождений, когда партии были зарегистрированы внутри конструктора Runnable?
2) Во втором результате статистика для прибывающих и необработанных на каждом этапе равна нулю (неверна).Итак, как получить правильные цифры для них?
Любая помощь приветствуется.