Re[4]: основы синхронизации потоков
От: Георгий Вячеславович  
Дата: 27.10.06 14:58
Оценка:
Здравствуйте, bolshik, Вы писали:


B>>>interface TimeListener {

B>>> /** Means that onTimeout() should be invoked one time in returned period in seconds. */
B>>> int getFrequency();
B>>> void onTimeout();
B>>>}

B>Т.е. джавадок на метод интерфейса это просто 'комментарий'? Дизайн чего здесь не продуман?


На мой взгляд, вы вынесли из класса часть логики, которой место в классе. У вас проверка наступления события происходит не в классе, реализующем TimeListener. Ваш дизайн не позволит произвольно переписать логику определения момента наступления события. getFrequency() перекладывает на клиента необходимость отслеживания наступления события.

Вы не можете клиента заставить вызывать onTimeout() в нужный момент, используя средства языка. Поэтому вы начинаете городить огород с комментарием. Да, javadoc — это всего лишь комментарий. Он ни к чему не обязывает. В итоге у вас часть внутреннего состояния дублируется (сам объект значет, как часто его надо вызывать, но вот количество тактов у вас для каждого объекта храниться во внешнем по отношению к класу хранилище).

Я бы такой дизайн не принял.


А вот за это двойку в дневник и родителей в школу. Это называется: "интерфейс я ввел, но продумывать модель исключений мне лень".
try {
    listener.onTimeout();
} catch (Exception ignore) {
}
Re[6]: основы синхронизации потоков
От: Георгий Вячеславович  
Дата: 27.10.06 15:00
Оценка:
Здравствуйте, bolshik, Вы писали:

B>Здравствуйте, Георгий Вячеславович, Вы писали:


B>Можно проще. А можно правильнее, хотя правильность — понятие относительное.


Чем больше кода, тем больше места для ошибок. Вот здесь
Автор: Георгий Вячеславович
Дата: 27.10.06
я написал про ошибки, которые вы допустили. Конечно, все в мире относительно и у вас может быть свое мнение по этому поводу.
Re[5]: основы синхронизации потоков
От: Георгий Вячеславович  
Дата: 27.10.06 15:05
Оценка:
Здравствуйте, Георгий Вячеславович, Вы писали:

ГВ>В итоге у вас часть внутреннего состояния дублируется (сам объект значет, как часто его надо вызывать, но вот количество тактов у вас для каждого объекта храниться во внешнем по отношению к класу хранилище).


Вот это беру назад. Не совсем это имел ввиду.
Re[3]: основы синхронизации потоков
От: Георгий Вячеславович  
Дата: 27.10.06 15:15
Оценка: 15 (1)
Вот мой вариант кода, как один из возможных:


package ru.rsdn.tests;

public class ThreadsTest {

    public static void main(String[] littleReds) throws InterruptedException {
        Timer timer = new Timer(1000);
        Thread spamerThread = new Thread(new Spamer("Hello! You won lots of money!!!", 5, timer));
        Thread antiSpamerThread = new Thread(new Spamer("Hate spamers!", 7, timer));
        spamerThread.setDaemon(true);
        antiSpamerThread.setDaemon(true);
        timer.setDaemon(true);
        spamerThread.start();
        antiSpamerThread.start();
        timer.start();
        Thread.sleep(10000);
    }
}

class Timer extends Thread {
    private final long delta;

    public Timer(long millis) {
        delta = millis;
    }

    public void run() {
        long sessionStartTimeMillis = System.currentTimeMillis();
        long millisToSleep = delta;
        while (true) {
            long startSleeping = System.currentTimeMillis();
            try {
                Thread.sleep(millisToSleep);
            } catch (InterruptedException e) {
                System.out.println("Interrupted");
            }

            if (System.currentTimeMillis() - startSleeping < millisToSleep) {
                millisToSleep -= System.currentTimeMillis() - startSleeping;
            } else {
                millisToSleep = delta;
                System.out.println("Since session started (seconds):" + (System.currentTimeMillis() - sessionStartTimeMillis) / 1000);
                synchronized(this) {
                    this.notifyAll();
                }
            }
        }
    }
}

class Spamer implements Runnable {
    private final String adv;
    private final int maxCount;
    private final Object monitor;

    public Spamer(String spamMess, int numberOfNotification, Object monitor) {
        adv = spamMess;
        maxCount = numberOfNotification;
        this.monitor = monitor;
    }

    public void run() {
        int count = 0;
        while (true) {
            synchronized(monitor) {
                try {
                    monitor.wait();
                } catch (InterruptedException e) {
                    System.out.println("Interrupted");
                    continue;
                }
            }
            ++count;
            if (count == maxCount) {
                System.out.println(adv);
                count = 0;
            }
        }
    }
}
Re[5]: основы синхронизации потоков
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 27.10.06 15:57
Оценка:
Здравствуйте, Георгий Вячеславович, Вы писали:

ГВ>На мой взгляд, вы вынесли из класса часть логики, которой место в классе. У вас проверка наступления события происходит не в классе, реализующем TimeListener. Ваш дизайн не позволит произвольно переписать логику определения момента наступления события. getFrequency() перекладывает на клиента необходимость отслеживания наступления события.


В таком виде контракт интерфейса понятен?
/**
 * Represents an object that is interested in timer service. An object should
 * provide timer with the information about interested frequency. Timer service
 * should notify the object with the specified frequency.
 */
interface TimeListener {
    /**
     * @return      interested frequency(1 time per returned number of seconds).
     */
    int getFrequency();

    /**
     * Is called by the timer service whith the specified frequency.
     */
    void onTimeout();
}



ГВ>Вы не можете клиента заставить вызывать onTimeout() в нужный момент, используя средства языка. Поэтому вы начинаете городить огород с комментарием. Да, javadoc — это всего лишь комментарий. Он ни к чему не обязывает. В итоге у вас часть внутреннего состояния дублируется (сам объект значет, как часто его надо вызывать, но вот количество тактов у вас для каждого объекта храниться во внешнем по отношению к класу хранилище).


ГВ>>Вот это беру назад. Не совсем это имел ввиду.


Ок


ГВ>Я бы такой дизайн не принял.


На здоровье.


ГВ>А вот за это двойку в дневник и родителей в школу. Это называется: "интерфейс я ввел, но продумывать модель исключений мне лень".

ГВ>
ГВ>try {
ГВ>    listener.onTimeout();
ГВ>} catch (Exception ignore) {
ГВ>}
ГВ>


Угу, это значит, что когда я выставляю MyTimer на всеобщее пользование и к нему, допустим, подключаются десять клиентов с нормальной имплементацией TimerListener, а потом подключается одиннадцатый, у которого интерфейс реализован как

public void onTimeout() {
    throw new RuntimeException("Just for fun");
}


то сервис должен отказать?
http://denis-zhdanov.blogspot.com
Re[6]: основы синхронизации потоков
От: Георгий Вячеславович  
Дата: 27.10.06 20:23
Оценка:
Здравствуйте, bolshik, Вы писали:

B>В таком виде контракт интерфейса понятен?

Он был понятен и в первом варианте. Я не о понятности говорил.


B>Угу, это значит, что когда я выставляю MyTimer на всеобщее пользование и к нему, допустим, подключаются десять клиентов с нормальной имплементацией TimerListener, а потом подключается одиннадцатый, у которого интерфейс реализован как


B>
B>public void onTimeout() {
B>    throw new RuntimeException("Just for fun");
B>}
B>


B>то сервис должен отказать?


А если такой код:

public void onTimeout() {
    throw new OutOfMemoryError();
}


или

public void onTimeout() {
    System.exit(0);
}

что будете делать?


Вашему интерфейсу я бы предпочел такой:
interface TimeListener {
    void onTimer() throws TimerException;
}


На мой взгляд, задача таймера — отсчитывать. Задача наблюдателя — реагировать. На каждый отсчет или через один — это дело наблюдателя, а не таймера. Каковы плюсы от реализации подсчета количества тактов в таймере?

P.S. Кроме того, задача на тему wait/notify. Хотя в условии и этого не сказанно.
Re[6]: основы синхронизации потоков
От: Георгий Вячеславович  
Дата: 27.10.06 20:29
Оценка:
Здравствуйте, bolshik, Вы писали:

B>Можно проще. А можно правильнее, хотя правильность — понятие относительное.


Первое не исключает второго.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.