powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Объясните по вложенной synchronized
4 сообщений из 4, страница 1 из 1
Объясните по вложенной synchronized
    #39677192
kevinlexus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дан класс с двумя методами, которые вызываются множеством потоков.
Не принимая во внимание дедлоки, объясните,
почему так нельзя использовать synchronized (вложенный), так как происходит эксепшн ErrorCountInHeap:


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
    private volatile Integer heap1=1500;
    private volatile Integer heap2=1500;

     * Переложить из кучки в кучку
     * @param cnt
     * @throws ErrorCountInHeap
     */
    public void moveFromHeap1ToHeap2(Integer cnt) throws ErrorCountInHeap {
        log.info("Перенести cnt={}", 100);
            synchronized (heap1) {
                synchronized (heap2) {
                    log.info("Lock1: heap1={}, heap2={}, баланс={}", heap1, heap2, heap1 + heap2);
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (heap1 <= 100) {
                        heap2 += heap1;
                        heap1 = 0;
                        log.info("Check1: heap1={}, heap2={}, баланс={}", heap1, heap2, heap1 + heap2);
                    } else {
                        heap1 -= 100;
                        log.info("Check2: heap1={}, heap2={}, баланс={}", heap1, heap2, heap1 + heap2);
                        heap2 += 100;
                        log.info("Check3: heap1={}, heap2={}, баланс={}", heap1, heap2, heap1 + heap2);
                    }
                    if (heap1 + heap2 != 3000) {
                        log.info("Баланс2 нарушен в кучке!: heap1={}, heap2={}, баланс={}", heap1, heap2, heap1 + heap2);
                        throw new ErrorCountInHeap("Баланс нарушен в кучке! Сейчас=" + (heap1 + heap2));
                    }
                    log.info("После обмена1: heap1={}, heap2={}, баланс={}", heap1, heap2, heap1+heap2);
                }
            }
    }

    /**
     * Переложить из кучки в кучку
     * @param cnt
     * @throws ErrorCountInHeap
     */
    public void moveFromHeap2ToHeap1(Integer cnt) throws ErrorCountInHeap {
        log.info("Перенести cnt={}", 100);
            synchronized (heap1) {
                synchronized (heap2) {
                    log.info("Lock2: heap1={}, heap2={}, баланс={}", heap1, heap2, heap1 + heap2);
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (heap2 <= 100) {
                        heap1 += heap2;
                        heap2 = 0;
                        log.info("Check4: heap1={}, heap2={}, баланс={}", heap1, heap2, heap1 + heap2);
                    } else {
                        heap2 -= 100;
                        log.info("Check5: heap1={}, heap2={}, баланс={}", heap1, heap2, heap1 + heap2);
                        heap1 += 100;
                        log.info("Check6: heap1={}, heap2={}, баланс={}", heap1, heap2, heap1 + heap2);
                    }
                    if (heap1 + heap2 != 3000) {
                        log.info("Баланс2 нарушен в кучке!: heap1={}, heap2={}, баланс={}", heap1, heap2, heap1 + heap2);
                        throw new ErrorCountInHeap("Баланс нарушен в кучке! Сейчас=" + (heap1 + heap2));
                    }
                    log.info("После обмена2: heap1={}, heap2={}, баланс={}", heap1, heap2, heap1 + heap2);
                }
            }
        }




Может всё таки не блокируются ресурсы heap1,heap2, но почему?
...
Рейтинг: 0 / 0
Объясните по вложенной synchronized
    #39677194
Alexander A. Sak
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я так понимаю, вся конструкция построена на предположении, что Integer мутабельный, и выражения вида heap1=0 меняют состояние, а не объект.
...
Рейтинг: 0 / 0
Объясните по вложенной synchronized
    #39677200
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexander A. SakЯ так понимаю, вся конструкция построена на предположении, что Integer мутабельный, и выражения вида heap1=0 меняют состояние, а не объект.
+1
volatile заменить на final
Integer на AtomicInteger
Лучше не станет, но будет немного работать.
...
Рейтинг: 0 / 0
Объясните по вложенной synchronized
    #39677203
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kevinlexus
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
    private volatile Integer heap1=1500;
    private volatile Integer heap2=1500;
...
            synchronized (heap1) {
                synchronized (heap2) {
...
                        heap2 += heap1;
                        heap1 = 0;
...

Может всё таки не блокируются ресурсы heap1,heap2, но почему?JLS8, 5.1.7 Boxing Conversion: "Ideally, boxing a primitive value would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques".
Требуется предсказуемость - работайте через API-класса, а не через магию компилятора.

Ещё лучше - не изобретать велосипед с квадратными колёсами даже в образовательных целях.
Потратьте время на изучение и использование уже существующего API.

P.S.
volatile на объект это осознанный шаг или "для надёжности".
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Объясните по вложенной synchronized
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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