Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Вопрос на понимание синхронизации / 11 сообщений из 11, страница 1 из 1
17.12.2012, 18:10:38
    #38082411
swerg
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос на понимание синхронизации
У меня есть синхронизация некого числа (long). Детали использования и область применения не важны.

Число надо увечивать и уменьшать на некие задаваемые значения и в случае креша сбрасывать в ноль.
Число должно быть синхронизировано.
Уменьшение/увеличение числа достигается через знак (пложителное/отрицаельное).
Плюс, есть константа ограничитель - при привышении кидаю эксепшен.
Понимаю, что кода под синхронайзд секцией должно быть меньше, но пока так.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
    private Object lockMonitor = new Object();
    private long mynumber = 0;

    private void change(long value) throws MaxExceededException {
        synchronized (lockMonitor) {
            if (value < 0) {
                mynumber += value;
            } else {
                if (mynumber + value< MAX_NUMBER) {
                    mynumber += value;
                } else {
                    throw new MaxStorageSizeExceededException("Limit.");
                }
            }
        }
    }

    private void clean() {
        synchronized (lockMonitor) {
                mynumber = 0;
        }
    }



Вопросы:
1. Будет ли работать синхронизаци для вторго блока (я думаю нет, но хочу понять почему)?
2. Может в этом случае использовать synchronized переменную?
3. Может надо применить другое решение? Плиз, пните мне в нужном направлении.
...
Рейтинг: 0 / 0
17.12.2012, 18:23:55
    #38082428
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос на понимание синхронизации
swerg1. Будет ли работать синхронизаци для вторго блока (я думаю нет, но хочу понять почему)?

Будет, только надо lockMonitor сделать final, чтобы никто другой монитор туда не записал.

swerg2. Может в этом случае использовать synchronized переменную?

Таких не бывает.

swerg3. Может надо применить другое решение? Плиз, пните мне в нужном направлении.
С точки зрения synchronized норм. Если в логику не вникать. А вообще, то есть AtomicLong и Lock.
...
Рейтинг: 0 / 0
17.12.2012, 18:33:15
    #38082436
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос на понимание синхронизации
Ещё стоит добавить volatile и синхронизировать чтение переменной. Тут бы ReadWriteLog и пригодился.
...
Рейтинг: 0 / 0
17.12.2012, 18:33:29
    #38082437
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос на понимание синхронизации
ReadWriteLock
...
Рейтинг: 0 / 0
17.12.2012, 18:44:16
    #38082451
swerg
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос на понимание синхронизации
Спасибо.

Ее походу читать вообще не надою Нужно лишь чекать превышение и тогда включать полную очистку.
...
Рейтинг: 0 / 0
17.12.2012, 18:52:12
    #38082460
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос на понимание синхронизации
Самый идеальный вариант - унаследоваться от AbstractQueuedSynchronizer и переопределить tryAcquireShared(), но это advanced use-case. Можно посмотреть в стандартной библиотеке - например Semaphore, CountdownLatch реализованы по похожей схеме.

А так да - Lock и AtomicLong попроще будут, единственно надо будет дописать логику по очистке при переполнении.
...
Рейтинг: 0 / 0
17.12.2012, 18:54:50
    #38082468
swerg
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос на понимание синхронизации
Стоит ли еще туда же запихать ConcurrentHashMap (нуно для скорости - не надо обходить граф при удалении вершин, кроче детали). Или нуно искать другой подход.

Код: 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.
    private Object lockMonitor = new Object();
    private final ConcurrentMap<String, Long> sizes = new ConcurrentHashMap<String, Long>();
    private long mynumber = 0;

    private void change(String key, long value) throws MaxExceededException {
        synchronized (lockMonitor) {
            if (value < 0) {
                mynumber += value;
                if (sizes.exists(key)) {
                    sizes.set(sizes.get(key) + value);
                } // TODO: check negative value
            } else {
                if (mynumber + value< MAX_NUMBER) {
                    mynumber += value;
                    if (sizes.exists(key)) {
                         sizes.put(key, sizes.get(key) + value);
                    } else {
                         sizes.put(key, value);
                    }
                } else {
                    throw new MaxStorageSizeExceededException("Limit.");
                }
            }
        }
    }

    private void clean() {
        synchronized (lockMonitor) {
                mynumber = 0;
                sizes.clean();
        }
    }
...
Рейтинг: 0 / 0
17.12.2012, 18:59:26
    #38082471
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос на понимание синхронизации
swergСтоит ли еще туда же запихать ConcurrentHashMap (нуно для скорости - не надо обходить граф при удалении вершин, кроче детали). Или нуно искать другой подход.

Код: 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.
    private Object lockMonitor = new Object();
    private final ConcurrentMap<String, Long> sizes = new ConcurrentHashMap<String, Long>();
    private long mynumber = 0;

    private void change(String key, long value) throws MaxExceededException {
        synchronized (lockMonitor) {
            if (value < 0) {
                mynumber += value;
                if (sizes.exists(key)) {
                    sizes.set(sizes.get(key) + value);
                } // TODO: check negative value
            } else {
                if (mynumber + value< MAX_NUMBER) {
                    mynumber += value;
                    if (sizes.exists(key)) {
                         sizes.put(key, sizes.get(key) + value);
                    } else {
                         sizes.put(key, value);
                    }
                } else {
                    throw new MaxStorageSizeExceededException("Limit.");
                }
            }
        }
    }

    private void clean() {
        synchronized (lockMonitor) {
                mynumber = 0;
                sizes.clean();
        }
    }



Тут не имеет особого смысла использовать ConcurrentMap для скорости - ибо боттлнек у вас в любом случае - это монитор. Тут хоть какая мапа - по барабану.
Ну и оффтоп - если уж используете ConcurrentMap, то у него есть метод putIfAbsent вместо exists()
...
Рейтинг: 0 / 0
17.12.2012, 19:03:10
    #38082477
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос на понимание синхронизации
Да и смысла в первом if я вообще не вижу, вы экономите на спичках, предполагаю что значение у вас будут чаще положительные чем ортицательные, да и якобы экономию на проверке mynumber + value< MAX_NUMBER - вы просто напросто теряете такой же проверкой вначале - if (value < 0), так что смысла в if вообще нет
...
Рейтинг: 0 / 0
17.12.2012, 19:08:00
    #38082487
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос на понимание синхронизации
ну и напоследок, я как параноик сделал бы или весь класс final или метод change
...
Рейтинг: 0 / 0
17.12.2012, 19:24:31
    #38082512
swerg
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос на понимание синхронизации
забыл ник,
вы правы накапливание будет только положительных значений. Как только вершина графа будет удаляться, я буду получать из мапа размер всех чайлдов (и буду вычитать из mynumber). Мне не надо будет их обходить; взять размер чайлда очень дрогостоящая операция.

Типа что-то такого:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
    private void deleteTopItem(String key) {
        synchronized (lockMonitor) {
           Long topItemSize = sizes.get(key);
           if (topItemSize != null) { // check if it's already deleted
                 mynumber -= 
                 sizes.remove(key);
           }
        }
    }
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Вопрос на понимание синхронизации / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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