Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > try/finally и делегат


Автор: xbarmaglot 14.2.2013, 16:02
есть примерный код
Код

            boolean status = m_device.start();
            if (status)
            {
                m_timer = new Timer();
                m_timer.schedule(new MyTimer(number)
                {
                    @Override
                    public void run()
                    {                        
                        m_device.stop();
                    }
                }, 60 * 60 * 1000); // Один час                 
            }


в m_device передается семафор, который захватывается при старте и освобождается при остановке.
Можно ли вынести блокировку семафора в делегат. Например:
Код

            boolean status = m_device.start();
            if (status)
            {
             m_semaphore.acquire();
             try
             {
                    m_timer = new Timer();
                    m_timer.schedule(new MyTimer(number)
                    {
                     @Override
                     public void run()
                     {                        
                         m_device.stop();
                     }
                 }, 60 * 60 * 1000); // Один час                                  
             }
             finally
             {
                 m_semaphore.release();    
             }                    
            }


Или делегат будет работать в контексте другого потока ?

Автор: LSD 14.2.2013, 16:45
Цитата(xbarmaglot @  14.2.2013,  17:02 Найти цитируемый пост)
Или делегат будет работать в контексте другого потока ?

Да, метод MyTimer.run() будет выполнен в потоке таймера.

Автор: xbarmaglot 14.2.2013, 17:02
Цитата(LSD @  14.2.2013,  16:45 Найти цитируемый пост)
Да, метод MyTimer.run() будет выполнен в потоке таймера.

а какие еще есть варианты решения. Просто я не могу гарантировать вызов stop после старт, что приведет к блокировке семафора.

Автор: LSD 14.2.2013, 17:37
Для твоих целей лучше подойдет http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Condition.html.

Автор: xbarmaglot 14.2.2013, 18:28
LSD, почему ? чем он лучше ?

Идея в следующем: есть несколько устройств, которые пишут данные в файлы в одну папку.
Есть поток, который собирает эти файлы, архивирует и отсылает.
Так вот пока хоть одно устройство пишет, поток ничего не должен делать. Иначе передаст битые файлы.

Семафор говорит о том, что задействован хотя бы один писатель.
Но проблема в том, что последовательность start/stop не может ныть гарантирована.
Количество start может не соответствовать количеству stop. Либо stop может вообще не быть.
Но если старт был, то транзакцию нужно завершить - иначе блокировка семафора.

Вот и возникла идея вынести finally наружу.

Автор: LSD 14.2.2013, 18:37
Тогда у тебя классический ReadWriteLock, потоки которые пишут файлы захватывают read lock. Поток который архивирует write lock.
Read lock можно захватить много, write lock только один и пока он захвачен, ни один read lock захватить нельзя.

Автор: xbarmaglot 14.2.2013, 18:48
Цитата(LSD @  14.2.2013,  18:37 Найти цитируемый пост)
Тогда у тебя классический ReadWriteLock, потоки которые пишут файлы захватывают read lock. Поток который архивирует write lock.
Read lock можно захватить много, write lock только один и пока он захвачен, ни один read lock захватить нельзя. 

так проблема в том, что писатель может захватить, но можен не освободить.
А семафор это или ReadWriteLock - пофигу

Добавлено через 1 минуту и 17 секунд
А возникает это потому, что start и stop вызываются в разных потоках.
Был бы один поток - try/finnaly решил бы проблему

Автор: korian 14.2.2013, 18:53
Цитата(xbarmaglot @  14.2.2013,  17:28 Найти цитируемый пост)
Но проблема в том, что последовательность start/stop не может ныть гарантирована.
Количество start может не соответствовать количеству stop. Либо stop может вообще не быть.

из-за чего эта проблема?
да и почему у вас старт и стоп не в одном потоке запускаются?
или что они вообще делают?
семафор надо лочить там, где будет делаться работа, и там же его освобождать, а не прыгать по потокам.

Автор: xbarmaglot 14.2.2013, 18:55
Цитата(korian @  14.2.2013,  18:53 Найти цитируемый пост)
из-за чего эта проблема?
да и почему у вас старт и стоп не в одном потоке запускаются?
или что они вообще делают?
семафор надо лочить там, где будет делаться работа, и там же его освобождать, а не прыгать по потокам. 

потому, что start и stop запускаются по разным событиям. Это системные события их запуск от меня не зависит

Автор: korian 14.2.2013, 19:09
Тогда опишите проблему детальнее.
Когда и что надо архивировать (или копировать) и как это привязано к загадачным старт и стоп.

Автор: xbarmaglot 14.2.2013, 19:11
Цитата(korian @  14.2.2013,  19:09 Найти цитируемый пост)
Тогда опишите проблему детальнее.
Когда и что надо архивировать (или копировать) и как это привязано к загадачным старт и стоп. 

а что не понятно в моем описании ?

Добавлено через 14 секунд
спрашивай...

Автор: korian 14.2.2013, 19:17
Цитата(xbarmaglot @  14.2.2013,  17:28 Найти цитируемый пост)
Идея в следующем: есть несколько устройств, которые пишут данные в файлы в одну папку.
Есть поток, который собирает эти файлы, архивирует и отсылает.
Так вот пока хоть одно устройство пишет, поток ничего не должен делать. Иначе передаст битые файлы.


ну если берем это описание то дето так:

Код

класс FileService {
    ReadWriteLock locker;

    public void добавитьФайл() {
        locker.lockRead();
        добавляем файл
        locker.unlockRead();
    }

    public заархивитьВсе() {
        locker.lockWrite();
        архивим
        locker.unlockWrite();
    }
}

 Ну и как бы готово.
Или есть какие-то проблемы, которые я не понимаю?

Автор: xbarmaglot 14.2.2013, 20:05
Цитата(korian @  14.2.2013,  19:17 Найти цитируемый пост)
Или есть какие-то проблемы, которые я не понимаю?

Есть - писатель делает так

Код

void start()
{
        locker.lockRead();
}

void stop()
{
        locker.unlockRead();
}


А они могут вызываться в любой последовательности и из разных потоках.
Может блокировать папку ?

Автор: korian 14.2.2013, 20:32
Цитата(xbarmaglot @  14.2.2013,  19:05 Найти цитируемый пост)
Есть - писатель делает так

Цитата(xbarmaglot @  14.2.2013,  19:05 Найти цитируемый пост)
Может блокировать папку ? 

Ну как бы, для начала хотелось бы понять, почему так получилось.

Автор: xbarmaglot 14.2.2013, 21:05
Цитата(korian @  14.2.2013,  20:32 Найти цитируемый пост)
Ну как бы, для начала хотелось бы понять, почему так получилось.

ну получается так

1. start, start - stop
2. start - stop
3. start - stop, stop
...

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

Добавлено через 1 минуту и 59 секунд
главный вопрос - как как в данном случае синхронизироваться, если старт и стоп в разных потоках вызываются.
Может отдельный поток заводить ?

Автор: korian 14.2.2013, 23:56
а почему семафор лочится на старте, а не на дейтсвии - т.е. перед записью в файл
и разлочивается при стопе, а не после того как запись совершилась?
короче тут как не крути но надо свести задачу к тому, что я написал
или переформулировать задачу в другую, а для этого надо детали.
Что такое девайс, что делает device.start, device.stop, почему они что-то лочат или разлочивают. Почему стоп и старт дергаются разными потоками. Это вообще разные процессы или один?

Автор: LSD 15.2.2013, 09:58
Сколько потоков пишут файл?

Автор: xbarmaglot 15.2.2013, 09:59
Цитата(korian @  14.2.2013,  23:56 Найти цитируемый пост)
а почему семафор лочится на старте, а не на дейтсвии - т.е. перед записью в файл
и разлочивается при стопе, а не после того как запись совершилась?

хороший вопрос

Цитата(korian @  14.2.2013,  23:56 Найти цитируемый пост)
Что такое девайс, что делает device.start, device.stop, почему они что-то лочат или разлочивают. Почему стоп и старт дергаются разными потоками. Это вообще разные процессы или один?

Это один процесс. device.start, device.stop просто пишут данные.
стоп и старт - дергаются при поступлении событий из системы - BroadcastReceiver.
Поэтому и разделена синхронизация. А вот как сделать атомарно - не знаю.

Да вроде деталей достаточно smile

Добавлено через 33 секунды
Цитата(LSD @  15.2.2013,  09:58 Найти цитируемый пост)
Сколько потоков пишут файл? 

могут писать до 6 потоком - сейчас. А вообще не обраниченно

Добавлено через 1 минуту и 22 секунды
Вернее все потоки пишут разные файлы

Автор: LSD 15.2.2013, 10:05
Цитата(xbarmaglot @  15.2.2013,  10:59 Найти цитируемый пост)
могут писать до 6 потоком - сейчас. А вообще не обраниченно 

Одновременно? В смысле используя один и тот же FileOutputStrean или по очереди открывая свой FileOutputStrean?


А теперь хотелось бы увидеть полный flow:
- Поступает внешнее событие device.start
- <описание того что должно произойти после start>
- Поступает внешнее событие device.stop
- <описание того что должно произойти после stop>

Автор: xbarmaglot 15.2.2013, 10:11
Цитата(LSD @  15.2.2013,  10:05 Найти цитируемый пост)
Одновременно? В смысле используя один и тот же FileOutputStrean или по очереди открывая свой FileOutputStrean?

Это все разные  FileOutputStrem. То есть каждый поток - свой файл.


Цитата(LSD @  15.2.2013,  10:05 Найти цитируемый пост)
- Поступает внешнее событие device.start
- <описание того что должно произойти после start>

создается файл и начинается запись.

Цитата(LSD @  15.2.2013,  10:05 Найти цитируемый пост)
Поступает внешнее событие device.stop
- <описание того что должно произойти после stop> 

заканчивается запись. закрывается файл.

Не думал, что это вызовет столько вопросов...

Автор: LSD 15.2.2013, 11:44
Цитата(xbarmaglot @  15.2.2013,  11:11 Найти цитируемый пост)
создается файл и начинается запись.

А откуда 6 потоков взялось? В каком порядке они работают?


Цитата(xbarmaglot @  15.2.2013,  11:11 Найти цитируемый пост)
заканчивается запись. закрывается файл.

А где архивация?



Цитата(xbarmaglot @  15.2.2013,  11:11 Найти цитируемый пост)
Не думал, что это вызовет столько вопросов... 

Извини конечно, но ты совершенно не умеешь объяснять, что требуется сделать.

Автор: xbarmaglot 15.2.2013, 12:15
Цитата(LSD @  15.2.2013,  11:44 Найти цитируемый пост)
А откуда 6 потоков взялось? В каком порядке они работают?

6 потоков - 6 устройств. Работают независимо друг от друга.


Цитата(LSD @  15.2.2013,  11:44 Найти цитируемый пост)
А где архивация?

архивация - это отдельный поток. Архивировать данные, пока хоть один поток пишет нет смысла.
Вот поэтому поток архивации и должен синхронизироваться с писателями.


Цитата(LSD @  15.2.2013,  11:44 Найти цитируемый пост)
Извини конечно, но ты совершенно не умеешь объяснять, что требуется сделать.

Да вроде проще некуда smile Есть писатели, а есть архиватор. Все это хозяйство должно быть синхроницированно.
Не знаю как проще объяснить...

Автор: LSD 15.2.2013, 13:07
Цитата(xbarmaglot @  15.2.2013,  13:15 Найти цитируемый пост)
6 потоков - 6 устройств. Работают независимо друг от друга.

Как они между собой арбитраж доступа к файлу реализуют?



Цитата(xbarmaglot @  15.2.2013,  13:15 Найти цитируемый пост)
архивация - это отдельный поток. Архивировать данные, пока хоть один поток пишет нет смысла.
Вот поэтому поток архивации и должен синхронизироваться с писателями.

Это уже понятно. Непонятно по какому условию активируется архивация. Что будет если в процессе архивации придет команда device.start? Почему надо блокировать архивацию по команде device.start а не тогда, когда начнется реальная запись в файл?

Автор: xbarmaglot 15.2.2013, 13:13
Цитата(LSD @  15.2.2013,  13:07 Найти цитируемый пост)
Как они между собой арбитраж доступа к файлу реализуют?

это разные файлы в одной директории


Цитата(LSD @  15.2.2013,  13:07 Найти цитируемый пост)
 Непонятно по какому условию активируется архивация

просто просыпается поток и пытается на семафоре определить, что никто не пишет


Цитата(LSD @  15.2.2013,  13:07 Найти цитируемый пост)
Что будет если в процессе архивации придет команда device.start? 

писатель будет ждять завершения архивации. эта операция довольно быстрая - 1-3 секунды. 
После того, как архивация закончится семафор освобождается и писатель начинает писать.


Цитата(LSD @  15.2.2013,  13:07 Найти цитируемый пост)
Почему надо блокировать архивацию по команде device.start а не тогда, когда начнется реальная запись в файл?

так при start и начинается реальная запись

Автор: LSD 15.2.2013, 14:31
Блин! Я тебя спросил:
Цитата(LSD @  15.2.2013,  10:58 Найти цитируемый пост)
Сколько потоков пишут файл?

ты ответил
Цитата(xbarmaglot @  15.2.2013,  10:59 Найти цитируемый пост)
могут писать до 6 потоком - сейчас. А вообще не обраниченно

а потом выясняется что:
Цитата(xbarmaglot @  15.2.2013,  14:13 Найти цитируемый пост)
это разные файлы в одной директории




В общем нет никаких проблем использовать RW lock, ему тут самое место.

Автор: xbarmaglot 15.2.2013, 15:40
Цитата(LSD @  15.2.2013,  14:31 Найти цитируемый пост)
а потом выясняется что:

я об этом сразу говорил, что это разные файлы


Цитата(LSD @  15.2.2013,  14:31 Найти цитируемый пост)
В общем нет никаких проблем использовать RW lock, ему тут самое место. 

что RWLock, что семафор - разницы нет.
Моя проблема в том, что может быть несколько start или stop подряд.
Или RW как раз и игнорируют эту проблему...

Автор: batigoal 15.2.2013, 18:19
xbarmaglot, дык это разрешено. Несколько start'ов - захват нескольких read-локов, stop - их освобождение. Архивация же захватывает write lock.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)