powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Задача по многопоточности
43 сообщений из 43, показаны все 2 страниц
Задача по многопоточности
    #38396675
mikhail_zh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день, коллеги.

Есть следующая задача. Необходимо реализовать обработчик событий. Что-то на подобии UIного диспатчера. Есть возможность регистрировать и удалять слушателей. Затем кидать события. Все события обрабатываются через слушателей в одном потоке. Сразу оговорюсь задача с собеседования, поэтому j.u.c.* просили не используется. Собственно вот мой вариант, просьба покритиковать.

Код: 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.
public class Dispatcher {

    public class Event {
        public final String toDo;

        public Event(String toDo) {
            this.toDo = toDo;
        }
    }

    public interface Listener {
        void dispatch(Event e);
    }

    private final Object listenersLock = new Object();
    private final Logger logger = Logger.getLogger("");
    private final Thread runner;
    private final List<Event> events = new ArrayList<Event>();
    private volatile List<Listener> listeners = new ArrayList<Listener>();

    public Dispatcher() {
        runner = new Thread(new Runnable() {
            public void run() {
                List<Event> toDispatch = new ArrayList<Event>();
                try {
                    while (!Thread.interrupted()) {
                        synchronized (events) {
                            while (events.isEmpty()) {
                                events.wait();
                            }
                            toDispatch.clear();
                            toDispatch.addAll(events);
                            events.clear();
                        }
                        for (Listener l : listeners) {
                            for (Event e : toDispatch) {
                                try {
                                    l.dispatch(e);
                                    if(Thread.interrupted()){
                                        throw new InterruptedException();
                                    }
                                } catch (Exception ex) {
                                    logger.warning("Dispatching error.");
                                    if (ex instanceof InterruptedException) {
                                        throw (InterruptedException) ex;
                                    }
                                }
                            }
                        }
                    }
                } catch (InterruptedException e) {
                    logger.info("Queue is stopped.");
                    return;
                }
            }
        });
    }

    public void addListener(Listener l) {
        synchronized (listenersLock) {
            List<Listener> newListeners = new ArrayList<Listener>(listeners);
            newListeners.add(l);
            listeners = newListeners;
        }
    }

    public void removeListener(Listener l) {
        synchronized (listenersLock) {
            List<Listener> newListeners = new ArrayList<Listener>(listeners);
            newListeners.remove(l);
            listeners = newListeners;
        }
    }

    public void dispatchEvent(Event e) {
        synchronized (events) {
            events.add(e);
            events.notifyAll();
        }
    }

    public void start() {
        runner.start();
    }

    public void stop() {
        runner.interrupt();
    }
}
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396697
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Копирования коллекций на каждом чихе конечно сильно режет глаз. Но с другой стороны. раз вым запретили использовать j.u.c, наверное других вариантом и нет.
Серьезное замечание только одно: для остановки диспатчера вы вызываете Thread.interrupt(). НО! У вас нет контроля за тем, какая-логика выполняется внутри листенера. Поэтому может получиться так, что внтури какого-нибудь листенера будет Thread.interrupted(), который очистит этот флаг. Как следствие - диспатчер не остановится.
Решение такое:
1) Добавить волатильный флажок stopped, и выставлять его в true в методе stop(). В while цикле и при итерировании по листенерам проверять его.
2) Оставить Thread.interrupt(), что бы ускорить выход из потока в случае, если листенер заблокировался на чем-нибудь.

Другое мелкое замечание: зачем вы руками бросаете InterruptedException, если оно никогда не уйдет за пределы вашей логики? В этом нет смысла.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396937
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikhail_zh,

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
public class Dispatcher {

    public class Event {
        public final String toDo;

        public Event(String toDo) {
            this.toDo = toDo;
        }
    }

    public interface Listener {
        void dispatch(Event e);
    }
...
}



Зачем Event у и Listener у быть нестатическими вложенными классами Dispatcher ?
То, что они нестатические --- вообще бред. То, что вложены в Dispatcher -- теоретически, допустимо, но в общем -- достаточно плохой дизайн, Event и Listener в общем-то никак не связаны с Dispatcher, последний их только использует.

Dispatcher лучше бы НАСЛЕДОВАТЬ от Thread, а не агрегировать его.

Ну и

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
                        synchronized (events) {
                            while (events.isEmpty()) {
                                events.wait();
                            }
                            toDispatch.clear();
                            toDispatch.addAll(events);
                            events.clear();
                        }

    public void dispatchEvent(Event e) {
        synchronized (events) {
            events.add(e);
            events.notifyAll();
        }
    }



Как думаешь, как это работать-то будет ?
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396940
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЗачем Event у и Listener у быть нестатическими вложенными классами Dispatcher ?
То, что они нестатические --- вообще бред. То, что вложены в Dispatcher -- теоретически, допустимо, но в общем -- достаточно плохой дизайн, Event и Listener в общем-то никак не связаны с Dispatcher, последний их только использует.С нестатическим event могу согласиться. Остальное - крайне спорные утверждения. Все зависит от того, как все это собираются использоваться. Если слушатели определяет исключительно разработчик - то их можно абсолютно спокойно оставить внутри Dispatcher, никакого криминала в этом нет. Если же их будет имплементировать юзер - тогда их действительно надо как минимум сделать static, а еще лучше вынести в отдельный класс.
Все эти разговоры про "плохой дизайн" вложенных классов идут буквально из нескольких книжек, где авторы, не утруждая себя внятными объяснениями, утверждают: "Нуууууу, вобще вложенный классы использовать достаточно плохо ..."
А с хрена ли их плохо использовать? Вы посмотрите на реализацию коллекций в Java - там все во вложенных классах. И ничего, никто не умер. Это абсолютно нормальная практика, когда дочерние сущности класса находятся внутри этого класса.

MasterZivDispatcher лучше бы НАСЛЕДОВАТЬ от Thread, а не агрегировать его.Это вообще за гранью добра и зла. Без каких-то очень-очень-очень серьезных причин наследоваться от Thread категорически нельзя. Во-первых, потому что переопределив методы Thread можно что-то ненароком сломать (например, getId()). А во-вторых, самое главное: зачем? Зачем наследоваться от Thread ? В задаче автора на то нет ни одной причины. Стандартная практика - implements Runnable.

MasterZiv
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
                        synchronized (events) {
                            while (events.isEmpty()) {
                                events.wait();
                            }
                            toDispatch.clear();
                            toDispatch.addAll(events);
                            events.clear();
                        }

    public void dispatchEvent(Event e) {
        synchronized (events) {
            events.add(e);
            events.notifyAll();
        }
    }


Как думаешь, как это работать-то будет ?А почему не будет?
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396944
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjv,

MasterZiv
Dispatcher лучше бы НАСЛЕДОВАТЬ от Thread, а не агрегировать его.
Это вообще за гранью добра и зла. Без каких-то очень-очень-очень серьезных причин наследоваться от Thread категорически нельзя. Во-первых, потому что переопределив методы Thread можно что-то ненароком сломать (например, getId()). А во-вторых, самое главное: зачем? Зачем наследоваться от Thread? В задаче автора на то нет ни одной причины. Стандартная практика - implements Runnable.

-- Это стандартная дебильная практика.

Я на самом деле видал дофига примеров наследования от Runable.
А, я наверное перепутал сутра Thread и Runable. Я имел в виду Runable.
А доводы на счёт "ненароком сломать" -- ну ... не ломай. :-)))
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396952
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjv
MasterZiv
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
                        synchronized (events) {
                            while (events.isEmpty()) {
                                events.wait();
                            }
                            toDispatch.clear();
                            toDispatch.addAll(events);
                            events.clear();
                        }

    public void dispatchEvent(Event e) {
        synchronized (events) {
            events.add(e);
            events.notifyAll();
        }
    }


Как думаешь, как это работать-то будет ?А почему не будет?

Входим в блок synchronized (events), events пуст, и мы начинаем ждать события на том же events.
Но оно никогда не наступит, потому что взводится оно только в dispatchEvent(Event e), в другом блоке synchronized (events) ,
в который нельзя будет зайти, поскольку монитор events уже заблокирован.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396953
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, вместо events.notifyAll(); должен быть events.notify(); Одно событие добавляется, какой смысл будить все ожидающие потоки ? достаточно одного.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396960
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivВходим в блок synchronized (events), events пуст, и мы начинаем ждать события на том же events.
Но оно никогда не наступит, потому что взводится оно только в dispatchEvent(Event e), в другом блоке synchronized (events) ,
в который нельзя будет зайти, поскольку монитор events уже заблокирован.Коллега, я вынужден констатировать, что вы не знаете, как работает wait/notify.
Когда вызывается wait(), то поток освобождает захваченный монитор , и помещается в wait set этого монитора. Поэтому в другой блок synchronized(events) можно будет зайти .
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396964
mikhail_zh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо за замечания:

1) Нестатичный Ивент класс - это косяк. Сделал их внутрениими просто для компактности. Вообще сам не злоупотребляю этим.
2) По воду остановки класса, это верно что нельзя опираться только на прерывание. Надо либо волотайл использовать либо атомарный булеан.
3) В цикле прохода по слушателям, действительно лучше break вставить вместо исключения на прерывание. Логику на исключениях лучше не строить.
4) Наследование от Thread и notify вместо notifyAll - очень спорные замечания.

MasterZiv...поскольку монитор events уже заблокирован.
при ожидании монитор разблокируется. ;)
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396967
greenpo1son
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Не пойму что забред код или я что-то не понимаю.
Почему вместо очереди вы используете ArrayList?
Скорей всего тут нужна не просто очередь, а приоритетная очередь.

Вот писал для себя очередь для обработки пакетов от клиента.

Код: 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.
package chatserver.NIO;


import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Iterator;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.log4j.Logger;


import chatserver.threading.PacketExecutor;

public class ExecutableQueue<T extends Runnable> implements Queue<T>, Runnable
{
    private static final int NONE = 0;
    private static final int QUEUED = 1;
    private static final int RUNNING = 2;
    private final PacketExecutor _executor;
    private final Queue<T> _queue;
    private AtomicInteger _state = new AtomicInteger(NONE);
    
    private static final Logger log = Logger.getLogger(ExecutableQueue.class);
    private static int count = 1;

    public ExecutableQueue(PacketExecutor executor)
    {
        _executor = executor;
        _queue = new ArrayDeque<T>();
    }

    @Override
    public void run()
    {
        while (_state.compareAndSet(QUEUED, RUNNING))
        {
   
            try
            {
                for (;;)
                {
                    final Runnable t = poll();
                    
                    
                    if (t == null)
                    {
                        break;
                    }
                    
                    t.run();
                }
            }
            finally
            {
                _state.compareAndSet(RUNNING, NONE);
            }
        }
    }

    @Override
    public int size()
    {
        return _queue.size();
    }

    @Override
    public boolean isEmpty()
    {
        return _queue.isEmpty();
    }

    @Override
    public boolean contains(Object o)
    {
        throw new UnsupportedOperationException();
    }

    @Override
    public Iterator<T> iterator()
    {
        throw new UnsupportedOperationException();
    }

    @Override
    public Object[] toArray()
    {
        throw new UnsupportedOperationException();
    }

    @Override
    public <E> E[] toArray(E[] a)
    {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean remove(Object o)
    {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean containsAll(Collection<?> c)
    {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean addAll(Collection<? extends T> c)
    {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean removeAll(Collection<?> c)
    {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean retainAll(Collection<?> c)
    {
        throw new UnsupportedOperationException();
    }

    @Override
    public void clear()
    {
        synchronized (_queue)
        {
            _queue.clear();
        }
    }

    @Override
    public boolean add(T e)
    {
        synchronized (_queue)
        {
            if (!_queue.add(e))
            {
                return false;
            }
        }

        if (_state.getAndSet(QUEUED) == NONE)
        {
            _executor.execute(this);
        }

        return true;
    }

    @Override
    public boolean offer(T e)
    {
        synchronized (_queue)
        {
            return _queue.offer(e);
        }
    }

    @Override
    public T remove()
    {
        synchronized (_queue)
        {
            return _queue.remove();
        }
    }

    @Override
    public T poll()
    {
        synchronized (_queue)
        {
            return _queue.poll();
        }
    }

    @Override
    public T element()
    {
        synchronized (_queue)
        {
            return _queue.element();
        }
    }

    @Override
    public T peek()
    {
        synchronized (_queue)
        {
            return _queue.peek();
        }
    }
}
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396968
greenpo1son
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вам просто подогнать под свой Executor который можете сами написать с 1 потоком.
Хотя мб я не понял задания.
Так же не понял почему здесь:
Код: java
1.
2.
3.
4.
5.
6.
7.
 public void addListener(Listener l) {
        synchronized (listenersLock) {
            List<Listener> newListeners = new ArrayList<Listener>(listeners);
            newListeners.add(l);
            listeners = newListeners;
        }
    }


Вы постоянно присваиваете новый ArrayList?
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396975
MaxNevermind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikhail_zh,

Код: java
1.
2.
3.
                            while (events.isEmpty()) {
                                events.wait();
                            }


А где обработка исключения? wait бросает InterruptedException
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396976
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
greenpo1son ,
Коллега, а что у вас делает метод ExecutableQueue.run()? Выглядит он отвратительнейшим образом. И зачем у ваша очередь имплементирует Runnable?
Без обид, но весь ваш код выглядит как очень кривой велосипед, написанный человеком, плохо разбирающимся в многопоточности.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396977
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaxNevermind ,
Код: java
1.
2.
3.
4.
                } catch (InterruptedException e) {
                    logger.info("Queue is stopped.");
                    return;
                }
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396978
MaxNevermind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mikhail_zh,

Код: 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.
                try {
                    while (!Thread.interrupted()) {
                        synchronized (events) {
                            while (events.isEmpty()) {
                                events.wait();
                            }
                            toDispatch.clear();
                            toDispatch.addAll(events);
                            events.clear();
                        }
                        for (Listener l : listeners) {
                            for (Event e : toDispatch) {
                                try {
                                    l.dispatch(e);
                                    if(Thread.interrupted()){
                                        throw new InterruptedException();
                                    }
                                } catch (Exception ex) {
                                    logger.warning("Dispatching error.");
                                    if (ex instanceof InterruptedException) {
                                        throw (InterruptedException) ex;
                                    }
                                }
                            }
                        }
                    }//<----------------------------------
                } catch (InterruptedException e) {
                    logger.info("Queue is stopped.");
                    return;
                }


Мне кажется или если interrupt случиться в указанной строчке, то сообщения "Queue is stopped." вообще не будет записано?
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396979
MaxNevermind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjv MaxNevermind ,
Код: java
1.
2.
3.
4.
                } catch (InterruptedException e) {
                    logger.info("Queue is stopped.");
                    return;
                }


Так он же при этом вообще остановиться, то есть диспатчер, а нужно чтобы он продолжил выполнение, так как добавилось новое событие
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396981
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaxNevermind ,
Когда поток интерраптается, это как правило означает, что он должен остановиться. А вы предлагаете проигнорировать interrupt(), и продолжить крутиться в цикле. Игнорирование интерраптов это как правило признак кривого кода.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396982
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaxNevermindМне кажется или если interrupt случиться в указанной строчке, то сообщения "Queue is stopped." вообще не будет записано?"Кажется". Вызов interrupt() выставляет в треде специальный булевский флажок. А условие в первом цикле while этот флажок проверяет.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396984
MaxNevermind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjv MaxNevermind ,
Когда поток интерраптается, это как правило означает, что он должен остановиться. А вы предлагаете проигнорировать interrupt(), и продолжить крутиться в цикле. Игнорирование интерраптов это как правило признак кривого кода.
http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396985
MaxNevermind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvMaxNevermindМне кажется или если interrupt случиться в указанной строчке, то сообщения "Queue is stopped." вообще не будет записано?"Кажется". Вызов interrupt() выставляет в треде специальный булевский флажок. А условие в первом цикле while этот флажок проверяет.
Ну да, флажок выставляется - цикл заканчивается - кэтч не срабатывает
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396994
greenpo1son
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
cdtyjv greenpo1son ,
Коллега, а что у вас делает метод ExecutableQueue.run()? Выглядит он отвратительнейшим образом. И зачем у ваша очередь имплементирует Runnable?
Без обид, но весь ваш код выглядит как очень кривой велосипед, написанный человеком, плохо разбирающимся в многопоточности. Интересно а вы подумайте как будет Executor или Пул выполнять не Runnable задачи??? Если так все плохо написано может быть вы предложите что-нибудь получше ,а я посмотрю??
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38396997
greenpo1son
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
greenpo1soncdtyjv greenpo1son ,
Коллега, а что у вас делает метод ExecutableQueue.run()? Выглядит он отвратительнейшим образом. И зачем у ваша очередь имплементирует Runnable?
Без обид, но весь ваш код выглядит как очень кривой велосипед, написанный человеком, плохо разбирающимся в многопоточности. Интересно а вы подумайте как будет Executor или Пул выполнять не Runnable задачи??? Если так все плохо написано может быть вы предложите что-нибудь получше ,а я посмотрю?? Или же вы не понимаете что такое ExecutableQueue?
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397028
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaxNevermind http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html Не совсем понял, к чему эта ссылка.
MaxNevermindНу да, флажок выставляется - цикл заканчивается - кэтч не срабатываетА, я невнимательно прочитал ваш комментарий. Вы акцентировали внимание на распечатку в логгер "queue is stopped". Да, согласен, не распечатается.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397029
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
greenpo1sonИнтересно а вы подумайте как будет Executor или Пул выполнять не Runnable задачи??? Если так все плохо написано может быть вы предложите что-нибудь получше ,а я посмотрю??
Или же вы не понимаете что такое ExecutableQueue?Если честно - я понятия не имею, что такое ExecutableQueue. Но это не мешает мне утверждать, что ваш код нужно выкинуть. Есть такое понятие - code smell. Это когда даже не вникая в то, что делает код, можно сказать, что он неверный, отталкиваясь от косвенных признаков. Так вот, ваш код очень сильно "смеллит". Я даже не хочу писать конкретные ошибки - их слишком много, и нет смысла их исправлять.

Давайте так - объясните вашу задачу. и я накидаю вам нормальное решение.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397045
greenpo1son
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
cdtyjvgreenpo1sonИнтересно а вы подумайте как будет Executor или Пул выполнять не Runnable задачи??? Если так все плохо написано может быть вы предложите что-нибудь получше ,а я посмотрю??
Или же вы не понимаете что такое ExecutableQueue?Если честно - я понятия не имею, что такое ExecutableQueue. Но это не мешает мне утверждать, что ваш код нужно выкинуть. Есть такое понятие - code smell. Это когда даже не вникая в то, что делает код, можно сказать, что он неверный, отталкиваясь от косвенных признаков. Так вот, ваш код очень сильно "смеллит". Я даже не хочу писать конкретные ошибки - их слишком много, и нет смысла их исправлять.

Давайте так - объясните вашу задачу. и я накидаю вам нормальное решение.
DOUBLE OMG. Нука хотябы одну ошибку в студию! Если вы даже не поняли что за класс перед вами , то что вы сможете объяснить ? Ссылаетесь не понятно на что.
Код этот работает так:

Например есть пул с 30 потоками. Приходит запрос ,в Селекторе читаем буффер и хандлим пакеты. Появились пакеты на отправку , добавляем их в эту очередь, при том это умная очередь которая способна распознать выполняются в ней пакеты или нет. То есть очередь не допустит что бы сразу 30 пакетов (запросов) не забрали все 30 потоков в пуле а достаточно что 1 поток обрабатывает всю очередь ... напишите мне альтернативу
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397046
greenpo1son
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
greenpo1soncdtyjvпропущено...
Если честно - я понятия не имею, что такое ExecutableQueue. Но это не мешает мне утверждать, что ваш код нужно выкинуть. Есть такое понятие - code smell. Это когда даже не вникая в то, что делает код, можно сказать, что он неверный, отталкиваясь от косвенных признаков. Так вот, ваш код очень сильно "смеллит". Я даже не хочу писать конкретные ошибки - их слишком много, и нет смысла их исправлять.

Давайте так - объясните вашу задачу. и я накидаю вам нормальное решение.
DOUBLE OMG. Нука хотябы одну ошибку в студию! Если вы даже не поняли что за класс перед вами , то что вы сможете объяснить ? Ссылаетесь не понятно на что.
Код этот работает так:

Например есть пул с 30 потоками. Приходит запрос ,в Селекторе читаем буффер и хандлим пакеты. Появились пакеты на отправку , добавляем их в эту очередь, при том это умная очередь которая способна распознать выполняются в ней пакеты или нет. То есть очередь не допустит что бы сразу 30 пакетов (запросов) не забрали все 30 потоков в пуле а достаточно что 1 поток обрабатывает всю очередь ... напишите мне альтернативу
Этот способ я использовал в Lineage2 когда разбирал сервак.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397051
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvMasterZivВходим в блок synchronized (events), events пуст, и мы начинаем ждать события на том же events.
Но оно никогда не наступит, потому что взводится оно только в dispatchEvent(Event e), в другом блоке synchronized (events) ,
в который нельзя будет зайти, поскольку монитор events уже заблокирован.Коллега, я вынужден констатировать, что вы не знаете, как работает wait/notify.
Когда вызывается wait(), то поток освобождает захваченный монитор , и помещается в wait set этого монитора. Поэтому в другой блок synchronized(events) можно будет зайти .

Да, действительно. Геслинг скрестил ежа с ужом...
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397058
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
greenpo1sonНука хотябы одну ошибку в студию!
Ошибка 1: Кривой дизайн. Коллекция имплементирует Runnable и хранит внутри себя Executor. Хотя должно быть с точностью наоборот: коллекция хранит внутри себя только элементы, не имплементирует Runnable, а какой-то Exeсutor вычитывает из нее.
Ошибка 2: Переменная _state нe final => не безопасная публикация.
Ошибка 3: isEmpty() и size() не обернуты в synchronized => могут возвращать совершенно некорректные результаты, вплоть до отрицательных величин.
Но самая главная претензия - это, конечно, дизайн. Он ужасен.

greenpo1sonКод этот работает так:
Например есть пул с 30 потоками. Приходит запрос ,в Селекторе читаем буффер и хандлим пакеты. Появились пакеты на отправку , добавляем их в эту очередь, при том это умная очередь которая способна распознать выполняются в ней пакеты или нет. То есть очередь не допустит что бы сразу 30 пакетов (запросов) не забрали все 30 потоков в пуле а достаточно что 1 поток обрабатывает всю очередь ... напишите мне альтернативуПока условие непонятно.
1) Сколько может быть таких очередей в рамках одного экзекьютора?
2) Что плохого в том, что они будут хэндлить пакеты в параллель? То есть, почему плохо, что 30 пакетов разойдутся по 30 потокам в пуле?

Пока что, до конца не понимая задачу, раз вам вы хотите исполнять в одном потоке, то вот решение:
Код: java
1.
ExecutorService executor = Executors.newFixedThreadPool(1);
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397060
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivДа, действительно. Геслинг скрестил ежа с ужом...Не понял вашей мысли. Поведение wait/notify - это классическое условие в не менее классическом мониторе Хоара.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397067
greenpo1son
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
cdtyjv,
Ошибка 3: isEmpty() и size() не обернуты в synchronized => могут возвращать совершенно некорректные результаты, вплоть до отрицательных величин.
Это обрабатывается внутри кода.

2) Что плохого в том, что они будут хэндлить пакеты в параллель? То есть, почему плохо, что 30 пакетов разойдутся по 30 потокам в пуле?
Представте себе что пользователь например игрок стреляет в игре , отходит ещё что нибудь делает , приходит пакеты запросы которые мы должны обработать в ПРАВИЛЬНОМ порядке! Если я сделаю так как вы предложили то подтверждение прыжка например придет быстрее чем подтверждения попадания в цель , хотя игрок с начала выстрелил,а только потом прыгнул.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397069
greenpo1son
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Точно такая же картина будет и у остальных игроков, у одного он прыгает у другого стреляет у 3 вообще летает ))
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397070
greenpo1son
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
greenpo1soncdtyjv,
Ошибка 3: isEmpty() и size() не обернуты в synchronized => могут возвращать совершенно некорректные результаты, вплоть до отрицательных величин.
Это обрабатывается внутри кода.

2) Что плохого в том, что они будут хэндлить пакеты в параллель? То есть, почему плохо, что 30 пакетов разойдутся по 30 потокам в пуле?
Представте себе что пользователь например игрок стреляет в игре , отходит ещё что нибудь делает , приходит пакеты запросы которые мы должны обработать в ПРАВИЛЬНОМ порядке! Если я сделаю так как вы предложили то подтверждение прыжка например придет быстрее чем подтверждения попадания в цель , хотя игрок с начала выстрелил,а только потом прыгнул.
И да не забывайте что мы все это записываем в ByteBuffer и если 30 потоков одновременно начнут записывать в 1 буффер то что произойдет ?
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397072
greenpo1son
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
greenpo1son,
Хотя они конечно записываются только в Селекторе, пул только подготавливает пакеты к записи в буффер.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397086
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
greenpo1son ,
Ок, ситуация проясняется. То есть вам нужен ордеринг в рамках одного игрока. Тогда вопрос такой: у вас сколько этих очередей? По одной на каждого игрока, или нет?
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397092
greenpo1son
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
cdtyjv greenpo1son ,
Ок, ситуация проясняется. То есть вам нужен ордеринг в рамках одного игрока. Тогда вопрос такой: у вас сколько этих очередей? По одной на каждого игрока, или нет?
У каждого игрока 2 очереди
Одна Executable для принятых пакетов, пакет прочитали и сразу исполнили всю очередь.
Второй простой ArrayDeque для содержание пакетов для отправки и добавления интересов в селектор (естественно синхронизованная)
По сабжу я хотел предложить ТС просто немного переделать мою очередь под 1 поток и юзать его вместо листов.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397109
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
greenpo1son ,
Ок, понял вас. Тогда к вашему коду следующие претензии:
1) Зачем вы имплементируете Queue, когда бОльшую часть ее методов вам не нужна? В результате, в классе куча ненужного кода.
2) Представим, что вы купили себе новый сервак с 16 ядрами. И в приложении создали тред пул с 16 потоками, который будет обрабатывать игроков. Они начинают играть, ходят, чатятся, закупаются, и т.д. Вроде все круто. Потом наступает вечер войн гильдий. В игру входит 16 + 1 = 17 игроков. И в какой-то момент они начинают слать очень много команд на ваш сервер: деруться, применяют аптечки, кастуют что-то, и т.д. Но у вас всего 16 потоков в пуле. Каждый из этих потоков начинает обрабатывать одного игрока, и никак не может выйти из run(), так как команды прибывают быстрее, чем обрабатываются. Результат: 16 игроков воюют нормально, а 17й не может ничего сделать, так как ваш тред пул никак не дойдет до его очереди. Это называется starvation.
3) В продолжении п.2, если игроки шлют больше команд, чем вы можете обработать, то они скапливаются, и со временем у вас вылетает OOME (хотя, может быть эта защита стоит у вас где-то в другом месте кода).

Я не знаю всех условий и особенностей вашей задачи, но я бы двигался примерно в таком направлении:
Код: 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.
public class TaskHolder {
    /** Максимальное количество запросов в очереди, что бы избежать OOME. */
    private final int maxSize;

    /** Маппинг с идентификатора игрока на группу задач. */
    private final Map<Long, TaskGroup> taskGrps = new LinkedHashMap<>();

    /** Очередь с группами задач. */
    private final BlockingQueue<Runnable> taskGrpQueue = new LinkedBlockingDeque<>();

    /** Общее количество задач в очереди. */
    private int size;

    /**
     * Конструктор.
     *
     * @param maxSize Максимальное количество задач в очереди.
     */
    public TaskHolder(int maxSize) {
        this.maxSize = maxSize;
    }

    /**
     * Добавить задачу в очередь.
     *
     * @param playerId Идентификатор игрока.
     * @param task Задача.
     */
    public synchronized void addTask(Long playerId, Runnable task) throws InterruptedException {
        // Ждем, пока не появится место в очереди.
        while (size >= maxSize)
            wait();

        TaskGroup taskGrp = taskGrps.get(playerId);

        if (taskGrp == null) {
            // Группы, ассоциированной с таким игроком, еще нет.
            taskGrp = new TaskGroup(playerId);

            taskGrp.tasks.add(task);

            taskGrps.put(playerId, taskGrp);

            taskGrpQueue.add(taskGrp);
        }
        else
            // Группа, ассоциированная с таким игроком, есть.
            taskGrp.tasks.add(task);

        size++;
    }

    /**
     * Получить очередь сгруппированных задач.
     *
     * @return Очередь сгруппированных задач.
     */
    public BlockingQueue<Runnable> taskGroupQueue() {
        return taskGrpQueue;
    }

    /**
     * Группа задач для одного игрока.
     */
    private class TaskGroup implements Runnable {
        /** Идентификатор игрока. */
        private final Long playerId;

        /** Задачи в данной группе. */
        private final Deque<Runnable> tasks = new ConcurrentLinkedDeque<>();

        /**
         * Конструктор.
         *
         * @param playerId Идентификатор игрока.
         */
        private TaskGroup(Long playerId) {
            this.playerId = playerId;
        }

        /** {@inheritDoc} */
        @Override public void run() {
            int tasksSize = tasks.size();

            // Вычитываем столько тасков, сколько их было в момент вызова
            // Метода run(). Иначе мы рисуем столкнуться со starvation, когда
            // постоянно прибывающие новые таски от одного игрока подавляют ранее
            // пришедшие таски от другого игрока.
            for (int i = 0; i < tasksSize; i++) {
                Runnable task = tasks.poll();

                synchronized (Handler.this) {
                    size--;

                    notifyAll();
                }

                try {
                    task.run();
                }
                catch (Exception e) {
                    // Обработка эксепшна, пришедшего из таска.
                }
            }

            synchronized (Handler.this) {
                // Если новых задач для данной группы не поступало, удалить ее.
                // Иначе - поставить в конец очереди.
                if (tasks.isEmpty())
                    taskGrps.remove(playerId);
                else
                    taskGrpQueue.add(this);
            }
        }
    }
}


То есть у нас есть класс TaskHolder с очень простым и понятным интерфейсом: добавить таск для конкретного игрока, получить список задач. Ваш NIO хэндлер закидывает сюда задачи, а какой-нибудь другой воркер в бесконечном цикле читает из taskGroupQueue(), и закидывает группу тасков в какой-нибудь executor.
Все, никаких ненужных методов нет, очередь ничего не знает про executor и никак от него не зависит, есть защита от starvation, есть защита от OOME.
Гонок вроде нет, но может быть я что-то и упустил.

Автору ваш совет не подходит, так как ему запретили использовать j.u.c, плюс у вас совершенно разные задачи: вам надо создать очередь задач, а ему по сути надо сделать воркер, который будет обрабатывать задачи в бесконечном цикле.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397115
greenpo1son
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
cdtyjv greenpo1son ,
Ок, понял вас. Тогда к вашему коду следующие претензии:
1) Зачем вы имплементируете Queue, когда бОльшую часть ее методов вам не нужна? В результате, в классе куча ненужного кода.
2) Представим, что вы купили себе новый сервак с 16 ядрами. И в приложении создали тред пул с 16 потоками, который будет обрабатывать игроков. Они начинают играть, ходят, чатятся, закупаются, и т.д. Вроде все круто. Потом наступает вечер войн гильдий. В игру входит 16 + 1 = 17 игроков. И в какой-то момент они начинают слать очень много команд на ваш сервер: деруться, применяют аптечки, кастуют что-то, и т.д. Но у вас всего 16 потоков в пуле. Каждый из этих потоков начинает обрабатывать одного игрока, и никак не может выйти из run(), так как команды прибывают быстрее, чем обрабатываются. Результат: 16 игроков воюют нормально, а 17й не может ничего сделать, так как ваш тред пул никак не дойдет до его очереди. Это называется starvation.
3) В продолжении п.2, если игроки шлют больше команд, чем вы можете обработать, то они скапливаются, и со временем у вас вылетает OOME (хотя, может быть эта защита стоит у вас где-то в другом месте кода).

Я не знаю всех условий и особенностей вашей задачи, но я бы двигался примерно в таком направлении:
Код: 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.
public class TaskHolder {
    /** Максимальное количество запросов в очереди, что бы избежать OOME. */
    private final int maxSize;

    /** Маппинг с идентификатора игрока на группу задач. */
    private final Map<Long, TaskGroup> taskGrps = new LinkedHashMap<>();

    /** Очередь с группами задач. */
    private final BlockingQueue<Runnable> taskGrpQueue = new LinkedBlockingDeque<>();

    /** Общее количество задач в очереди. */
    private int size;

    /**
     * Конструктор.
     *
     * @param maxSize Максимальное количество задач в очереди.
     */
    public TaskHolder(int maxSize) {
        this.maxSize = maxSize;
    }

    /**
     * Добавить задачу в очередь.
     *
     * @param playerId Идентификатор игрока.
     * @param task Задача.
     */
    public synchronized void addTask(Long playerId, Runnable task) throws InterruptedException {
        // Ждем, пока не появится место в очереди.
        while (size >= maxSize)
            wait();

        TaskGroup taskGrp = taskGrps.get(playerId);

        if (taskGrp == null) {
            // Группы, ассоциированной с таким игроком, еще нет.
            taskGrp = new TaskGroup(playerId);

            taskGrp.tasks.add(task);

            taskGrps.put(playerId, taskGrp);

            taskGrpQueue.add(taskGrp);
        }
        else
            // Группа, ассоциированная с таким игроком, есть.
            taskGrp.tasks.add(task);

        size++;
    }

    /**
     * Получить очередь сгруппированных задач.
     *
     * @return Очередь сгруппированных задач.
     */
    public BlockingQueue<Runnable> taskGroupQueue() {
        return taskGrpQueue;
    }

    /**
     * Группа задач для одного игрока.
     */
    private class TaskGroup implements Runnable {
        /** Идентификатор игрока. */
        private final Long playerId;

        /** Задачи в данной группе. */
        private final Deque<Runnable> tasks = new ConcurrentLinkedDeque<>();

        /**
         * Конструктор.
         *
         * @param playerId Идентификатор игрока.
         */
        private TaskGroup(Long playerId) {
            this.playerId = playerId;
        }

        /** {@inheritDoc} */
        @Override public void run() {
            int tasksSize = tasks.size();

            // Вычитываем столько тасков, сколько их было в момент вызова
            // Метода run(). Иначе мы рисуем столкнуться со starvation, когда
            // постоянно прибывающие новые таски от одного игрока подавляют ранее
            // пришедшие таски от другого игрока.
            for (int i = 0; i < tasksSize; i++) {
                Runnable task = tasks.poll();

                synchronized (Handler.this) {
                    size--;

                    notifyAll();
                }

                try {
                    task.run();
                }
                catch (Exception e) {
                    // Обработка эксепшна, пришедшего из таска.
                }
            }

            synchronized (Handler.this) {
                // Если новых задач для данной группы не поступало, удалить ее.
                // Иначе - поставить в конец очереди.
                if (tasks.isEmpty())
                    taskGrps.remove(playerId);
                else
                    taskGrpQueue.add(this);
            }
        }
    }
}


То есть у нас есть класс TaskHolder с очень простым и понятным интерфейсом: добавить таск для конкретного игрока, получить список задач. Ваш NIO хэндлер закидывает сюда задачи, а какой-нибудь другой воркер в бесконечном цикле читает из taskGroupQueue(), и закидывает группу тасков в какой-нибудь executor.
Все, никаких ненужных методов нет, очередь ничего не знает про executor и никак от него не зависит, есть защита от starvation, есть защита от OOME.
Гонок вроде нет, но может быть я что-то и упустил.

Автору ваш совет не подходит, так как ему запретили использовать j.u.c, плюс у вас совершенно разные задачи: вам надо создать очередь задач, а ему по сути надо сделать воркер, который будет обрабатывать задачи в бесконечном цикле.

Зачем это все?
Во первых буффер не резиновый , а всего 32кб + кеш буфферов 64шт.
Во вторых есть определенный тайм оут который определяет время первого пакета на отправку после которого пишутся пакеты,
так же имеется ограничители на max кол-во пакетов и также размер запроса не может привышать 32кб (в 32кб может поместится около 500 пакетов) и если же начнется такой хаус (500 пакетов это уже не нормально, нормально считает 32 пакета за раз) то просто кикаем игрока.
Ваш метод мне кажется не подходит, так как не допустимо ждать пока освободится место в очереди.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397117
greenpo1son
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
1) Зачем вы имплементируете Queue, когда бОльшую часть ее методов вам не нужна? В результате, в классе куча ненужного кода.
Для совместимости , и работа на уровне суперкласса как бы поощряется.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397132
cdtyjv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
greenpo1son1) Зачем вы имплементируете Queue, когда бОльшую часть ее методов вам не нужна? В результате, в классе куча ненужного кода.
Для совместимости , и работа на уровне суперкласса как бы поощряется.Для совместимости с чем? И факт того, что вы имплементируете интерфейс коллекции таким образом, что:
1) Половина методов тупо не заимплементирована, включая iterator()!!!
2) Часть заимплементированных методов работают некорректно (size(), isEmpty(),
... не может поощряться.
Это какой-то класс мутант, который вроде бы и коллекция ... но как коллекцию его использовать нельзя.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397137
mikhail_zh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
greenpo1son
Код: java
1.
2.
3.
4.
5.
6.
7.
 public void addListener(Listener l) {
        synchronized (listenersLock) {
            List<Listener> newListeners = new ArrayList<Listener>(listeners);
            newListeners.add(l);
            listeners = newListeners;
        }
    }


Вы постоянно присваиваете новый ArrayList?

Да, это самопальный CopyOnWrite . Т.к. слушатели редко изменяются и часто читаются, то думаю подход оправдан. На сколько мне известно этот метод для слушателей в Свинге используется.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397139
greenpo1son
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
cdtyjvgreenpo1son1) Зачем вы имплементируете Queue, когда бОльшую часть ее методов вам не нужна? В результате, в классе куча ненужного кода.
Для совместимости , и работа на уровне суперкласса как бы поощряется.Для совместимости с чем? И факт того, что вы имплементируете интерфейс коллекции таким образом, что:
1) Половина методов тупо не заимплементирована, включая iterator()!!!
2) Часть заимплементированных методов работают некорректно (size(), isEmpty(),
... не может поощряться.
Это какой-то класс мутант, который вроде бы и коллекция ... но как коллекцию его использовать нельзя.
Все верно сделано потому что это не коллекция , а рабочий queue к которому прямого доступа из когда нету. Ему не нужен итератор,
так все запросы обрабатываются в нем ,а не через него. То что я вам показал это всего 1% из всего кода.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397140
greenpo1son
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Для совместимости с чем? И факт того, что вы имплементируете интерфейс коллекции таким образом, что:
С тем что любой другой программист может дописать или как то улучшить и просто поменять конкретный объект, а не весь связанный с ним код.
...
Рейтинг: 0 / 0
Задача по многопоточности
    #38397173
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cdtyjvMasterZivДа, действительно. Геслинг скрестил ежа с ужом...Не понял вашей мысли. Поведение wait/notify - это классическое условие в не менее классическом мониторе Хоара.

Зачем event сопрягать с семафором?

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


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