Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Наивная реализация ConcurrentHashMap / 15 сообщений из 15, страница 1 из 1
11.08.2015, 00:19
    #39026697
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наивная реализация ConcurrentHashMap
Дали задачку написать ConcurrentHashMap для long.

Я что-то не вкурил в чем суть немного зачем именно для лонга.

Первое, что в голову приходит, это создать класс, у которого будет массив HasMap. Допустим их изначально будет 16.

или даже не HashMap-ов, а обёрток HashMap-ов , которые оборачивает операции чтения в readLock,а мутабельные операции во writeLock.


Что вы думаете? в том направлении мыслю?
...
Рейтинг: 0 / 0
11.08.2015, 08:38
    #39026748
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наивная реализация ConcurrentHashMap
questionerЯ что-то не вкурил в чем суть немного зачем именно для лонга.
...
Рейтинг: 0 / 0
11.08.2015, 08:39
    #39026751
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наивная реализация ConcurrentHashMap
questionerЯ что-то не вкурил в чем суть немного зачем именно для лонга.

Возможно, потому что запись и чтение long не атомарны?
...
Рейтинг: 0 / 0
11.08.2015, 09:24
    #39026785
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наивная реализация ConcurrentHashMap
Blazkowicz,

Вроде нет. Можно и int и short оказывается. На выбор, что больше нравится
...
Рейтинг: 0 / 0
11.08.2015, 13:11
    #39027000
scf
scf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наивная реализация ConcurrentHashMap
Так в исходниках всё написано:
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/java/util/concurrent/ConcurrentHashMap.java#107

Брать CHM из Java8 за образец не советую - там очень сложная реализация.

Почему для лонга - потому, что стандартный CHM работает только с объектами, а специализированный для примитивов должен быть быстрее.

И - обязательно сделай тесты под разными профилями нагрузки. Чтобы они показывали, насколько твоя реализация круче стандартной.
...
Рейтинг: 0 / 0
11.08.2015, 16:28
    #39027184
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наивная реализация ConcurrentHashMap
scfТак в исходниках всё написано:
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/java/util/concurrent/ConcurrentHashMap.java#107

Брать CHM из Java8 за образец не советую - там очень сложная реализация.

Почему для лонга - потому, что стандартный CHM работает только с объектами, а специализированный для примитивов должен быть быстрее.

И - обязательно сделай тесты под разными профилями нагрузки. Чтобы они показывали, насколько твоя реализация круче стандартной.

У меня просто представление, что CHM это такая мапа, которая, внутри себя содержит несколько мап и если происходит запись, то лочится только одна из этих мап.

открыв исходники я что-то не увидел подмап никаких
...
Рейтинг: 0 / 0
12.08.2015, 11:26
    #39027659
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наивная реализация ConcurrentHashMap
scfТак в исходниках всё написано:
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/java/util/concurrent/ConcurrentHashMap.java#107

Брать CHM из Java8 за образец не советую - там очень сложная реализация.

Почему для лонга - потому, что стандартный CHM работает только с объектами, а специализированный для примитивов должен быть быстрее.

И - обязательно сделай тесты под разными профилями нагрузки. Чтобы они показывали, насколько твоя реализация круче стандартной.

у примитива хэшкод проще посчитать. поэтому "круче" что ли?
...
Рейтинг: 0 / 0
12.08.2015, 13:13
    #39027808
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наивная реализация ConcurrentHashMap
questionerУ меня просто представление, что CHM это такая мапа, которая, внутри себя содержит несколько мап и если происходит запись, то лочится только одна из этих мап.
Это "представление" чем-то обусловлено?
...
Рейтинг: 0 / 0
12.08.2015, 13:29
    #39027829
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наивная реализация ConcurrentHashMap
questioner,

У примитива удаление записью null не с имитируешь.


Вопрос к ТС - а long это ключ или значение?
...
Рейтинг: 0 / 0
12.08.2015, 20:13
    #39028150
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наивная реализация ConcurrentHashMap
BlazkowiczquestionerУ меня просто представление, что CHM это такая мапа, которая, внутри себя содержит несколько мап и если происходит запись, то лочится только одна из этих мап.
Это "представление" чем-то обусловлено?

Чтивами всякими. Исходники какие-то слишком сложные
...
Рейтинг: 0 / 0
12.08.2015, 20:13
    #39028151
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наивная реализация ConcurrentHashMap
Сергей Арсеньевquestioner,

У примитива удаление записью null не с имитируешь.


Вопрос к ТС - а long это ключ или значение?

Ключ
...
Рейтинг: 0 / 0
12.08.2015, 20:14
    #39028154
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наивная реализация ConcurrentHashMap
Blazkowicz,

Вот есть такой вариант... но что-то я предвижу здесь миллион косяков.

помогите поправить

Код: 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.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
class ConcurrentIntHashMap {

    private transient Entry table[];

    private transient int count;

    private int threshold;

    private float loadFactor;

    private static class Entry {

        int hash;
        int key;
        Object value;
        Entry next;
        ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
        Lock readLock = readWriteLock.readLock();
        Lock writeLock = readWriteLock.writeLock();

        protected Entry(int hash, int key, Object value, Entry next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

        public int getHash() {
            return hash;
        }

        public Lock getWriteLock() {
            return writeLock;
        }

        public Lock getReadLock() {
            return readLock;
        }
    }

    public ConcurrentIntHashMap() {
        this(20, 0.75f);
    }

    public ConcurrentIntHashMap(int initialCapacity) {
        this(initialCapacity, 0.75f);
    }

    public ConcurrentIntHashMap(int initialCapacity, float loadFactor) {
        super();
        if (initialCapacity < 0) {
            throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity);
        }
        if (loadFactor <= 0) {
            throw new IllegalArgumentException("Illegal Load: " + loadFactor);
        }
        if (initialCapacity == 0) {
            initialCapacity = 1;
        }

        this.loadFactor = loadFactor;
        table = new Entry[initialCapacity];
        threshold = (int) (initialCapacity * loadFactor);
    }

    public int size() {
        return count;
    }

    public boolean isEmpty() {
        return count == 0;
    }

    public boolean contains(Object value) {
        if (value == null) {
            throw new NullPointerException();
        }

        Entry tab[] = table;
        for (int i = tab.length; i-- > 0; ) {
            Entry e = tab[i];
            if (e != null) {
                e.getReadLock().lock();
                try {

                    for (; e != null; e = e.next) {
                        if (e.value.equals(value)) {
                            return true;
                        }
                    }
                } finally {
                    e.getReadLock().unlock();
                }
            }
        }
        return false;
    }

    public boolean containsValue(Object value) {
        return contains(value);
    }

    public boolean containsKey(int key) {
        Entry tab[] = table;
        int hash = key;
        int index = (hash & 0x7FFFFFFF) % tab.length;
        Entry e = tab[index];
        if (e != null) {
            e.getReadLock().lock();
            try {

                for (; e != null; e = e.next) {
                    if (e.hash == hash) {
                        return true;
                    }
                }
            } finally {
                e.getReadLock().unlock();
            }
        }
        return false;
    }

    public Object get(int key) {
        Entry tab[] = table;
        int hash = key;
        int index = (hash & 0x7FFFFFFF) % tab.length;
        Entry e = tab[index];
        if (e != null) {
            e.getReadLock().lock();
            try {
                for (; e != null; e = e.next) {
                    if (e.hash == hash) {
                        return e.value;
                    }
                }
            } finally {
                e.getReadLock().unlock();
            }
        }
        return null;
    }

    protected synchronized void rehash() {
        int oldCapacity = table.length;
        Entry oldMap[] = table;

        int newCapacity = oldCapacity * 2 + 1;
        Entry newMap[] = new Entry[newCapacity];

        threshold = (int) (newCapacity * loadFactor);
        table = newMap;

        for (int i = oldCapacity; i-- > 0; ) {
            for (Entry old = oldMap[i]; old != null; ) {
                Entry e = old;
                old = old.next;

                int index = (e.hash & 0x7FFFFFFF) % newCapacity;
                e.next = newMap[index];
                newMap[index] = e;
            }
        }
    }

    public Object put(int key, Object value) {
        // Makes sure the key is not already in the hashtable.
        Entry tab[] = table;
        int hash = key;
        int index = (hash & 0x7FFFFFFF) % tab.length;
        Entry e = tab[index];
        if (e != null) {
            e.getWriteLock().lock();
            try {

                for (; e != null; e = e.next) {
                    if (e.hash == hash) {
                        Object old = e.value;
                        e.value = value;
                        return old;
                    }
                }
            } finally {
                e.getWriteLock().unlock();
            }
        }

        if (count >= threshold) {
            // Rehash the table if the threshold is exceeded
            rehash();

            tab = table;
            index = (hash & 0x7FFFFFFF) % tab.length;
        }

        Entry newEntry = new Entry(hash, key, value, tab[index]);
        tab[index] = newEntry;
        count++;
        return null;
    }

    public Object remove(int key) {
        Entry tab[] = table;
        int hash = key;
        int index = (hash & 0x7FFFFFFF) % tab.length;
        Entry e = tab[index];
        if (e != null) {
            e.getWriteLock().lock();
            try {
                for (Entry prev = null; e != null; prev = e, e = e.next) {
                    if (e.hash == hash) {
                        if (prev != null) {
                            prev.next = e.next;
                        } else {
                            tab[index] = e.next;
                        }
                        count--;
                        Object oldValue = e.value;
                        e.value = null;
                        return oldValue;
                    }
                }
            } finally {
                e.getWriteLock().unlock();
            }
        }
        return null;
    }

    public synchronized void clear() {
        Entry tab[] = table;
        for (int index = tab.length; --index >= 0; ) {
            tab[index] = null;
        }
        count = 0;
    }
}
...
Рейтинг: 0 / 0
13.08.2015, 11:35
    #39028445
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наивная реализация ConcurrentHashMap
questioner
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
                e.getReadLock().lock();
                try {

                    for (; e != null; e = e.next) {
                        if (e.value.equals(value)) {
                            return true;
                        }
                    }
                } finally {
                    e.getReadLock().unlock();
                }
...
Рейтинг: 0 / 0
13.08.2015, 11:39
    #39028449
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наивная реализация ConcurrentHashMap
В этом варианте такого не было.
...
Рейтинг: 0 / 0
13.08.2015, 13:14
    #39028591
questioner
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Наивная реализация ConcurrentHashMap
Сергей АрсеньевВ этом варианте такого не было.

Сергей - зоркий глаз.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Наивная реализация ConcurrentHashMap / 15 сообщений из 15, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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