powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Почему этот код иногда приводит к дедлоку?
16 сообщений из 16, страница 1 из 1
Почему этот код иногда приводит к дедлоку?
    #39745470
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
public class Test {
    static {
        final int SUM = IntStream.range(0, 100)
                .parallel()
                .reduce(new IntBinaryOperator() {
                    @Override
                    public int applyAsInt(int n, int m) {
                        return sum(n, m);
                    }
                })
                .getAsInt();
    }

    private static int sum(int n, int m) {
        return n + m;
    }

    public static void main(String[] args) {
        System.out.println("Finished");
    }
}



на моей машине это код ИНОГДА заканчивается дедлоком, а как иногда проходит нормально. Как это можно объяснить?
...
Рейтинг: 0 / 0
Почему этот код иногда приводит к дедлоку?
    #39745478
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если метод sum сунуть внутрь IntBinaryOperator, то дедлок не случается

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
public class Test {
    static {
        final int SUM = IntStream.range(0, 100)
                .parallel()
                .reduce(new IntBinaryOperator() {
                    private int sum(int n, int m) {
                        return n + m;
                    }
                    @Override
                    public int applyAsInt(int n, int m) {
                        return sum(n, m);
                    }
                })
                .getAsInt();
    }



    public static void main(String[] args) {
        System.out.println("Finished");
    }
}
...
Рейтинг: 0 / 0
Почему этот код иногда приводит к дедлоку?
    #39745727
mad_nazgul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questioner,

В первом случае sum - статичный метод.
Во втором - нет.

По этому в первом deadlock, а во втором нет. :-)
...
Рейтинг: 0 / 0
Почему этот код иногда приводит к дедлоку?
    #39745775
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mad_nazgulquestioner,

В первом случае sum - статичный метод.
Во втором - нет.

По этому в первом deadlock, а во втором нет. :-)

А почему в первом случается ИНОГДА, а не всегда?
...
Рейтинг: 0 / 0
Почему этот код иногда приводит к дедлоку?
    #39745854
mad_nazgul
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionermad_nazgulquestioner,

В первом случае sum - статичный метод.
Во втором - нет.

По этому в первом deadlock, а во втором нет. :-)

А почему в первом случается ИНОГДА, а не всегда?

Потому что, как повезет. :-)
...
Рейтинг: 0 / 0
Почему этот код иногда приводит к дедлоку?
    #39745867
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mad_nazgulquestionerпропущено...


А почему в первом случается ИНОГДА, а не всегда?

Потому что, как повезет. :-)

А можете объяснить кейс при котором везёт?
...
Рейтинг: 0 / 0
Почему этот код иногда приводит к дедлоку?
    #39745960
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Можно даже ещё проще ту же проблему сделать:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
public class Test {
    static {
        System.out.println("static initializer: " + Thread.currentThread().getName());

        final long SUM = IntStream.range(0, 5)
                .parallel()
                .mapToObj(i -> {
                    System.out.println("map: " + Thread.currentThread().getName() + " " + i);
                    return i;
                })
                .count();
    }

    public static void main(String[] args) {
        System.out.println("Finished");
    }
}



Точно такая же ерунда - иногда нормально проходит, а иногда(почти всегда) зависает
...
Рейтинг: 0 / 0
Почему этот код иногда приводит к дедлоку?
    #39746044
dimonz80
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
questionerМожно даже ещё проще ту же проблему сделать:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
public class Test {
    static {
        System.out.println("static initializer: " + Thread.currentThread().getName());

        final long SUM = IntStream.range(0, 5)
                .parallel()
                .mapToObj(i -> {
                    System.out.println("map: " + Thread.currentThread().getName() + " " + i);
                    return i;
                })
                .count();
    }

    public static void main(String[] args) {
        System.out.println("Finished");
    }
}



Точно такая же ерунда - иногда нормально проходит, а иногда(почти всегда) зависает

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
  /**
     * Prints a String and then terminate the line.  This method behaves as
     * though it invokes <code>{@link #print(String)}</code> and then
     * <code>{@link #println()}</code>.
     *
     * @param x  The <code>String</code> to be printed.
     */
    public void println(String x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }
...
Рейтинг: 0 / 0
Почему этот код иногда приводит к дедлоку?
    #39746139
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
dimonz80
questionerМожно даже ещё проще ту же проблему сделать:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
public class Test {
    static {
        System.out.println("static initializer: " + Thread.currentThread().getName());

        final long SUM = IntStream.range(0, 5)
                .parallel()
                .mapToObj(i -> {
                    System.out.println("map: " + Thread.currentThread().getName() + " " + i);
                    return i;
                })
                .count();
    }

    public static void main(String[] args) {
        System.out.println("Finished");
    }
}



Точно такая же ерунда - иногда нормально проходит, а иногда(почти всегда) зависает


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
  /**
     * Prints a String and then terminate the line.  This method behaves as
     * though it invokes <code>{@link #print(String)}</code> and then
     * <code>{@link #println()}</code>.
     *
     * @param x  The <code>String</code> to be printed.
     */
    public void println(String x) {
        synchronized (this) {
            print(x);
            newLine();
        }
    }





Ну это всё прям объясняет
...
Рейтинг: 0 / 0
Почему этот код иногда приводит к дедлоку?
    #39746294
Фотография Пылинка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Потому что Fork/Join имеет скорее академический интерес, реально не может управлять внутренними join. "result in a stall (thread in a wait state) when the recursion level becomes long." Годится для быстрых операций (убрали SUM() ВНУТРЬ - работает). Никаких блокировок, вводов/выводов и методов синхронизации использовать нельзя.
PS По-моему, это исключает серьезное использование многопоточных stream, основанных на F/J, а так, побаловаться на собеседовании.
...
Рейтинг: 0 / 0
Почему этот код иногда приводит к дедлоку?
    #39746315
maxkar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerна моей машине это код ИНОГДА заканчивается дедлоком, а как иногда проходит нормально. Как это можно объяснить?

Ну уже правильно объяснили - везет иногда :). Это пример на class initialization deadlock из вашей соседней темы (правда в данном случае - с самим собой). Ну т.е. main->stream->workers done->some (non-current thread) worker->main. Плюс особенности реализации Fork/Join где вызывающий поток тоже выполняет вычисления. И некоторая задержка на инициализацию пула, потоков и всех остальных локов в worker thread.

В первом случае вы вызваете sum на Test, который еще не до конца инициализирован (не отработал static initializer). Поэтому все потоки, обращающиеся к классу Test (кроме main thread) будут ждать. Для FJP - все потоки кроме main при вызове sum будут ждать завершения инициализаци Test, которая в свою очередь ждет завершения вычислений. Если вдруг main успел все обсчитать до других потоков (у него лок на инициализацию Test) - тогда все работает. Увеличьте range или добавьте sleep небольшой - будет стабильнее блокироваться.

Во втором примере у вас анонимный класс. Его экземпляр создается в main потоке (все необходимые обращения к Test - допускаются). Экземпляр самодостаточный (к классу Test он не обращается), поэтому все workers могут отработать нормально.

Третий пример (с лямбдой) полностью аналогичен первому примеру с дополнительной задержкой. Курите javap -private -v Test. Интересные места - метод lambda$static$0 и BootstrapMethods (которое в конце). В переводе на человеческий, на месте лямбды в коде будет сгенерирован класс, реализующий IntFunction и вызывающий Test.lambda$static$0.
...
Рейтинг: 0 / 0
Почему этот код иногда приводит к дедлоку?
    #39746609
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
maxkar,

авторВ первом случае вы вызваете sum на Test, который еще не до конца инициализирован (не отработал static initializer). Поэтому все потоки, обращающиеся к классу Test (кроме main thread) будут ждать. Для FJP - все потоки кроме main при вызове sum будут ждать завершения инициализаци Test, которая в свою очередь ждет завершения вычислений. Если вдруг main успел все обсчитать до других потоков (у него лок на инициализацию Test) - тогда все работает. Увеличьте range или добавьте sleep небольшой - будет стабильнее блокироваться.

Вы будете удивлены, но иногда дедлока не случается даже в случае, когда воркеры обсчитывают лямбду
...
Рейтинг: 0 / 0
Почему этот код иногда приводит к дедлоку?
    #39746698
alex55555
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
questionerВы будете удивлены, но иногда дедлока не случается даже в случае, когда воркеры обсчитывают лямбду
Вы будете удивлены, но такие заявления не появляются, когда автор хоть что-то понимает.

Повторюсь - вам сначала читать научиться надо.
...
Рейтинг: 0 / 0
Почему этот код иногда приводит к дедлоку?
    #39746731
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alex55555questionerВы будете удивлены, но иногда дедлока не случается даже в случае, когда воркеры обсчитывают лямбду
Вы будете удивлены, но такие заявления не появляются, когда автор хоть что-то понимает.

Повторюсь - вам сначала читать научиться надо.

И что же автор конкретно не понимает?
...
Рейтинг: 0 / 0
Почему этот код иногда приводит к дедлоку?
    #39746783
Фотография Пылинка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maxkarВ первом случае вы вызваете sum на Test, который еще не до конца инициализирован (не отработал static initializer). Поэтому все потоки, обращающиеся к классу Test (кроме main thread) будут ждать. Для FJP - все потоки кроме main при вызове sum будут ждать завершения инициализаци Test, которая в свою очередь ждет завершения вычислений. Если вдруг main успел все обсчитать до других потоков (у него лок на инициализацию Test) - тогда все работает. Увеличьте range или добавьте sleep небольшой - будет стабильнее блокироваться.
Не могу согласиться, работают все потоки (у меня их 8, включая main), поэтому при range=100 у меня вообще никак не падает. ЗАТО ПРИ УВЕЛИЧЕНИИ RANGE стабильно падает после выполнения примерно 80-83% работы (r=400 -> 335, r=1000 -> 830 операций, при r=10 000 немного больше 8 000), видимо начинается "кража работы".
...
Рейтинг: 0 / 0
Почему этот код иногда приводит к дедлоку?
    #39755562
questioner
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Почему этот код иногда приводит к дедлоку?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]