Всем привет, есть задание:
На вход передается целое число, больше 0, кратное 2 (n). Создается два потока, работающих
параллельно, каждый поток в цикле, считывает значение из файла out.txt увеличивает
его на 1, выводит в консоли старое значение, новое значение и идентификатор потока
(идентификатор может быть произвольным), и записывает обратно в файл.
В конечном итоге оба потока должны успешно завершить свою работу, и в консоль
должно вывестись содержимое файла out.txt (которое должно быть равно заданному
на входе n).
Пытаюсь сделать так:
private static final Semaphore semaphore = new Semaphore(1);
public void execute() {
threadOne.start();
threadTwo.start();
}
private void task() {
try {
semaphore.acquire();
while (incrementValue()) {
incrementValue();
semaphore.release();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private boolean incrementValue() {
try {
Scanner reader = new Scanner(new FileReader(FILE_NAME));
int value = Integer.parseInt(reader.nextLine());
if (value == n) {
return false;
}
FileWriter writer = new FileWriter(FILE_NAME);
writer.write(String.valueOf(value + 1));
System.out.printf("Thread: %s, old - %d, new - %d", Thread.currentThread().getName(), value, ++value);
System.out.println();
writer.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
Thread: Thread-0, old - 0, new - 1
Thread: Thread-0, old - 1, new - 2
Thread: Thread-0, old - 2, new - 3
Thread: Thread-1, old - 2, new - 3
Thread: Thread-0, old - 3, new - 4
Thread: Thread-1, old - 3, new - 4
Как сделать так, чтобы потоки поочередно записывали в файл? Заранее благодарю за помощь.
Сразу целая куча проблем:
incrementValue
вызывается два раза. Сначала в условии цикла while
и еще раз в теле. Делайте раз в теле и присваивайте переменной, которую и проверяйте в условии.flush
делать, а полностью закрывать. Пользуйтесь try-with-resourcesВот так (плюс изменения по работе с файлами) работает лучше:
boolean toContinue = true;
while (toContinue) {
semaphore.acquire();
toContinue = incrementValue();
semaphore.release();
Thread.sleep(1); // см. пояснения ниже
}
Строка с sleep
необязательна, но дело в том, что после отпускания семафора JVM необязательно отдаст управление другому потоку. Переключение между потоками довольно накладная операция и поэтому слишком часто JVM ее не делает. При малых значениях n
квант времени выделенный для выполнения первому потоку может и не завершиться и тогда он опять захватит семафор. На моей системе один поток успевает сделать около 200 переключений, пока планировщик не отдаст управление другому потоку (это если без sleep
). sleep
же (немного) уравнивает шансы, т.е. это сигнал планировщику, что данный поток хочет отдать управление. (Также можно использовать Thread.yield()
или Thread.sleep(0)
, но с ними тот же поток чаще продолжает выполнение по крайне мере у меня на системе).
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
При тестовом просмотре сайта на ноуте, выдало вот такую дичьПодскажите, как правильно рассчитывать высоту экрана, чтобы смотрелось хорошо...
Хочу получить значение со страницы из input при помощи python, но куда ни глянь - везде используют Django или Jinja2Можно ли как-то обойтись без них?
как написать media в перевернутом виде в bootstrap 4? col-12 col-sm-6 col-md-3 так сделал но sm в перевернутом виде не поддерживает