Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Объясните по вложенной synchronized / 4 сообщений из 4, страница 1 из 1
21.07.2018, 08:05
    #39677192
kevinlexus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объясните по вложенной synchronized
Дан класс с двумя методами, которые вызываются множеством потоков.
Не принимая во внимание дедлоки, объясните,
почему так нельзя использовать 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
21.07.2018, 08:33
    #39677194
Alexander A. Sak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объясните по вложенной synchronized
Я так понимаю, вся конструкция построена на предположении, что Integer мутабельный, и выражения вида heap1=0 меняют состояние, а не объект.
...
Рейтинг: 0 / 0
21.07.2018, 09:45
    #39677200
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объясните по вложенной synchronized
Alexander A. SakЯ так понимаю, вся конструкция построена на предположении, что Integer мутабельный, и выражения вида heap1=0 меняют состояние, а не объект.
+1
volatile заменить на final
Integer на AtomicInteger
Лучше не станет, но будет немного работать.
...
Рейтинг: 0 / 0
21.07.2018, 10:03
    #39677203
Basil A. Sidorov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Объясните по вложенной synchronized
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
Форумы / Java [игнор отключен] [закрыт для гостей] / Объясните по вложенной synchronized / 4 сообщений из 4, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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