А>2) Если я хочу положить ЧАСТЬ данных внутри функции класса под тотже мьютекс что и synchronized методах я могу использовать synchronized(this). Так?
1) думаю да, за исключением static методов
The synchronized statement (§14.18) computes a reference to an object; it then attempts to perform a lock action on that object and does not proceed further until the lock action has successfully completed. (A lock action may be delayed because the rules about locks can prevent the main memory from participating until some other thread is ready to perform one or more unlock actions.) After the lock action has been performed, the body of the synchronized statement is executed. If execution of the body is ever completed, either normally or abruptly, an unlock action is automatically performed on that same lock.
A synchronized method (§8.4.3.6) automatically performs a lock action when it is invoked; its body is not executed until the lock action has successfully completed. If the method is an instance method, it locks the lock associated with the instance for which it was invoked (that is, the object that will be known as this during execution of the body of the method). If the method is static, it locks the lock associated with the Class object that represents the class in which the method is defined. If execution of the method's body is ever completed, either normally or abruptly, an unlock action is automatically performed on that same lock.
Здравствуйте, Волк-Призрак, Вы писали:
ВП>Насчёт инкапсуляции не думаю, просто "static-оболочка существует 1м экземпляре в любом случае в 1м экземпляре". А так то что если методы статиеские есть то это не значит, что я могу выполнить ВП>
ВП>myobject.privatevariable=newvalue;
ВП>
ВП>из произвольного кода, знающео о соота классе и имеющем ссылку на myobject.
Тут я не правильно выразился. Я имел ввиду не инкапсуляцию дынных а, так сказать, инкапсуляцию реализации. Статичесие методы жестко привязаны к классам, в которых они объявлены. Статические методы нельзя привязать к абстакным интерфесам. То есть класс, пользующийся статическими методами обязан знать о классе, в которых они объявлены, вместо того что бы знать интерфес объекта, который ему нужен для получения от него (объекта) некоторой функциональности.
Да и по поводу инкапсуляции дынных. Обычно для исользования статических методов (функциональных) обычно вызывают некоторые другие статические методы (сервисные), дабы параметризировать статическое состояние класса, требуемое в функциональных методах, что открывает реализацию класса (в том числе и для клиентов функциональных классов).
ВП>Конечно, следуе логике профессионального когдинга, я должен слелать так, что соединение загрузки классов загрузчику "делегируется в конструкторе" или передаётся после создания в спецметод в виде интерфейса
Точно! Помнишь принцип Голивуда "Не звоните нам, мы сами с вами свяжемся"
ВП>
ВП>И передавать этот интерфейс в конструктор/спецметод загрузчика...
Типа того. Только поубирать
NullPointerException — его вообще выскакивать в правильной программе не должно, если выскакивает надо править код где оно выскакивает
SecurityException — аналогично, только надо править код в том месте, где вызывается метод
SocketException — сразу говорит о том, что мы используем сокеты. А если я захочу грузить классы из БД?
ВП>Я использую static методы "для оптимизации" потому что когда в силу проектных решений объект сущестыует в единственом экземпляре (что не ухудшает функционалую часть программы), я оформляю его в виде класса со статическими методами.
Заметил? Все таки объект — это объект, и будет лучше если он им и останется.
ВП>Потому что в статические методы не передаётся "неявный аргумент объекта". а если работа с SharedJDBCConnection идёт постоянно и интенсивно, то... хотя крохи но "наптимизировать" можно. "Курочка по зёрнышку, а убирать авгиевый курятник пришел Геракл"
Вот при таком подходе никакой Геракл никогда не разгребет твои конюшни
Здравствуйте,
А>1) Привильно ли я понимаю, что следующие два куска кода эквивалентны?
Нет. Синхронизация метода блокирует метод, синхронизация this блокирует инстанс объекта.
А>2) Если я хочу положить ЧАСТЬ данных внутри функции класса под тотже мьютекс что и synchronized методах я могу использовать synchronized(this). Так?
Нет. Синхронизация происходит по средствам семафоров, в качестве которых выступают объекты JVM. Cинхронизация по this — это синхронизация по инстансу объекта класса. Именно эту синхронизацию не рекомендуется использовать, так как это блокирует доступ к объекту целиком (в синхронизированных участках кода этого объекта будет всего один тред, причем, если участков много, то это приведет к тому, что все треды будут ждать пока какойнидуть один не выйдет из какого нибудь одного блока).
Здравствуйте, Lucker, Вы писали:
L> Во-первых, метод помеченный как синхронизированный синхронизируется на объекте, которому он принадлежит, в случае instance метода (и т.д. по спецификации) а не на отдельном объекте для каждого такого метода. L> Во-вторых, зачем синхронизировать доступ к отдельному методу? Синхронизация необходима для предотвращения одновременного доступа к объекту, что бы не нарушить инвариантность его состояния. Если для некоторого метода необходимо синхронизировать доступ к некоторому подможеству состояния объекта (читай подможеству атрибутов) нежели в остальных методах, имеет смысл подумать о "выделении класса"! L>[/list]
Да, не прав я, только что проверил. Экивалентны действительно, по крайней мере на винде.
Звиняюсь
синхронизация
От:
Аноним
Дата:
17.12.04 10:58
Оценка:
1) Привильно ли я понимаю, что следующие два куска кода эквивалентны?
public synchronized vod f()
{
//....(*)
}
и
public vod f()
{
synchronized(this)
{
//....(*)
}
}
2) Если я хочу положить ЧАСТЬ данных внутри функции класса под тотже мьютекс что и synchronized методах я могу использовать synchronized(this). Так?
Здравствуйте, Аноним, Вы писали:
D>>Логически -- да. Однако они компилируются в различный байт-код.
А>Ну мне не важно во что они компилируются. Т.е. я могу этим пользоваться?
Нужно использовать там, где:
1. В действительности синхронизировать нужно контретную "усовно небольшую" операцию (1-2 оператора), а всякие там подготовку и преобразование аргументов, обработку результатов работы синхронищруемого кода, это конечно лучше в асинхронном виде делать, когда возможно.
Например если по принципу пинг-понг (запрос-немедленный_ответ) делать загрузку классов, то лучше выделить процесс собственно пиг-понга в отдельный метод. Когда соединение существет в единственном экземпляре и shared на нескоько потоков, такой метод имхо лучше объявить static.
У кого есть дельные возражения (с аргументами типа "<большинство VM это не проглотит|в спецификации есть <*>, изза чего "static-оптимизация" не работатает, такой трюк не работает итп, см. <список иточником или оптимальных ключевых слов поиска>"). Как говорится, discussion is opened and answers are welcome*.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
while(Life.getClass().getClassLoader()==Religion.GOD){Life.be();};
Скажи .net корпорации Microsoft! (c) ghostwolf 2004
7 раз поищи в стандартной библиотеке, 1 раз накодь своё.
Здравствуйте, Волк-Призрак, Вы писали:
ВП>Например если по принципу пинг-понг (запрос-немедленный_ответ) делать загрузку классов, то лучше выделить процесс собственно пиг-понга в отдельный метод. Когда соединение существет в единственном экземпляре и shared на нескоько потоков, такой метод имхо лучше объявить static. ВП>У кого есть дельные возражения (с аргументами типа "<большинство VM это не проглотит|в спецификации есть <*>, изза чего "static-оптимизация" не работатает, такой трюк не работает итп, см. <список иточником или оптимальных ключевых слов поиска>"). Как говорится, discussion is opened and answers are welcome*.
Вот если бы в java ключевым моментом была оптимизация кода, то я бы все равно раз десять подумал перед созданием static-метода, потому что static-метоы отбирают основные преимужества OOП — инкапсуляцию и полиморфизм. Исполняемому потоку абсолютно незачем знать колько у тебя соединений, он просто должен знать что для его работы нужно соединение. Так же ему не нужно знать как это соединение получается, он просто должен знать что для его работы нужно соединение. Вот в этом случае, когда вдруг понадобится сдлать к систме не одно соединение, а скажем, использовать пул — код рабочего потока останется неизменным, он так же должен остаться неизменным когда поменяются правила создания новыз соединений. Так что 7 раз подумай и постарайся ниразу не использовать static метод (ну за некоторыми исключениями).
Здравствуйте, Lucker, Вы писали:
L>Вот если бы в java ключевым моментом была оптимизация кода, то я бы все равно раз десять подумал перед созданием static-метода, потому что static-метоы отбирают основные преимужества OOП — инкапсуляцию и полиморфизм.
Насчёт инкапсуляции не думаю, просто "static-оболочка существует 1м экземпляре в любом случае в 1м экземпляре". А так то что если методы статиеские есть то это не значит, что я могу выполнить
myobject.privatevariable=newvalue;
из произвольного кода, знающео о соота классе и имеющем ссылку на myobject.
А вот насчёт полиморфихма Вы правы 123%.
L> Исполняемому потоку абсолютно незачем знать колько у тебя соединений, он просто должен знать что для его работы нужно соединение. Так же ему не нужно знать как это соединение получается, он просто должен знать что для его работы нужно соединение.
Эээ... Он же должен както себе его взять:? А то у Вас получается, что ему и знать ничего ненадо о самом способе получения соединения. Как же объект сможет использовать соединение. если он сам его берёт, но не знает, у кого?
Сейчас у меня именно так сделан класс загрузчика. Т. е. загрузчик сам создаёт Socket, берёт из него потоки, и тп итд. И сам следит, что ему делать при разрыве коннекта во время скачивания класса, итп.
Конечно, следуе логике профессионального когдинга, я должен слелать так, что соединение загрузки классов загрузчику "делегируется в конструкторе" или передаётся после создания в спецметод в виде интерфейса
И передавать этот интерфейс в конструктор/спецметод загрузчика...
Просто в силу "физиологии клинтстких соединений" может быть только одно "соедиение данных" и одно "классовое соединение". Причём загружаемые через классовое соединение модули клиента вообще ничего не знают о каких то там BOOMClientClassLoader и прочих чудесах. Об этом знаеттолько класс Launcher, который создаёт экземпляр и устанавливает свойства моего загрузчика. А потом им загружает класс Starter, котрый методом start начинает выполнение программы. L> Вот в этом случае, когда вдруг понадобится сдлать к систме не одно соединение, а скажем, использовать пул — код рабочего потока останется неизменным, он так же должен остаться неизменным когда поменяются правила создания новыз соединений. Так что 7 раз подумай и постарайся ниразу не использовать static метод (ну за некоторыми исключениями).
Он за пределами загрузчика и так не меняется (когда я добавляю новую экранную форму, остальной код сервера и клиента обэтом не знает, так как именна классов форм привязаны к действиям через таблицу в БД.
Я использую static методы "для оптимизации" потому что когда в силу проектных решений объект сущестыует в единственом экземпляре (что не ухудшает функционалую часть программы), я оформляю его в виде класса со статическими методами.
Потому что в статические методы не передаётся "неявный аргумент объекта". а если работа с SharedJDBCConnection идёт постоянно и интенсивно, то... хотя крохи но "наптимизировать" можно. "Курочка по зёрнышку, а убирать авгиевый курятник пришел Геракл"
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
while(Life.getClass().getClassLoader()==Religion.GOD){Life.be();};
Скажи .net корпорации Microsoft! (c) ghostwolf 2004
7 раз поищи в стандартной библиотеке, 1 раз накодь своё.
Здравствуйте, Lucker, Вы писали:
L>Тут я не правильно выразился. Я имел ввиду не инкапсуляцию дынных а, так сказать, инкапсуляцию реализации.
Одно сово добавил, а как поменялось вс — вот великий и могучий во всей красе.
*содрогается при мысли о языке программирования C^C, на котром пишешь, как на человеческом...*
L>Статичесие методы жестко привязаны к классам, в которых они объявлены. Статические методы нельзя привязать к абстакным интерфесам. То есть класс, пользующийся статическими методами обязан знать о классе, в которых они объявлены, вместо того что бы знать интерфес объекта, который ему нужен для получения от него (объекта) некоторой функциональности.
Ну да... я както не подумал о таких зависимостях. да и про
что открывает реализацию класса (в том числе и для клиентов функциональных классов).
я тоже не подумал...
ВП>>Конечно, следуе логике профессионального когдинга, я должен слелать так, что соединение загрузки классов загрузчику "делегируется в конструкторе" или передаётся после создания в спецметод в виде интерфейса
L>Точно! Помнишь принцип Голивуда "Не звоните нам, мы сами с вами свяжемся"
вообще то, оно у меня ассацируется со шпионами и CCCP vs NATO, а не с голивудом (в 22 года то — что будет в 52?) ВП>>
ВП>>И передавать этот интерфейс в конструктор/спецметод загрузчика...
L>Типа того. Только поубирать L>
L>NullPointerException — его вообще выскакивать в правильной программе не должно, если выскакивает надо править код где оно выскакивает L>SecurityException — аналогично, только надо править код в том месте, где вызывается метод L>SocketException — сразу говорит о том, что мы используем сокеты. А если я захочу грузить классы из БД? L>
Э..... Вообщето я привык писать "пуленепробиваемый код", который не знает, что он в моей тепличной программе работает, и "готов к любым неожиданностям" (вроде того что какойнибудь новый модуль Системы пишется пьяным в зюзю кодером например....) — да мало ли почему вдруг "null приедет в гости")
SecurityException и SocketException я использовал чтобы в премере не городить классы исключений. А так SecurityException превращаеются NoPermissionForClassException (это имя более ясно объясняет, что именно помешало скачать класс — сервер запретил). SocketException можно конечно "заменить на" NetworkProblemException, но и тот же SocketException можно выбрасывать независимо от реализации ("преобразовывать" TelepaticConnectionCorruptedExcetion в SocketException конструкций типа catch(Type1 err){throw new Type2(args);. ).
L>Заметил? Все таки объект — это объект, и будет лучше если он им и останется.
Мдя.... Придётся перелопатить пару классов весьма и весьма ( JDBCSharedConnection и самый "законнектенный" класс SessionsController). Ну и всё что их, центральные модули моей системы , использует, тоже перелопатить, но уже Replace In Path )
L>Вот при таком подходе никакой Геракл никогда не разгребет твои конюшни
Учтём-с...
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
while(Life.getClass().getClassLoader()==Religion.GOD){Life.be();};
Скажи .net корпорации Microsoft! (c) ghostwolf 2004
7 раз поищи в стандартной библиотеке, 1 раз накодь своё.
Здравствуйте, aefimov, Вы писали:
A>Здравствуйте,
А>>1) Привильно ли я понимаю, что следующие два куска кода эквивалентны?
A>Нет. Синхронизация метода блокирует метод, синхронизация this блокирует инстанс объекта.
Ого! Вот это настоящие принципиальные отличия....
A>Нет. Синхронизация происходит по средствам семафоров, в качестве которых выступают объекты JVM. Cинхронизация по this — это синхронизация по инстансу объекта класса. Именно эту синхронизацию не рекомендуется использовать, так как это блокирует доступ к объекту целиком (в синхронизированных участках кода этого объекта будет всего один тред, причем, если участков много, то это приведет к тому, что все треды будут ждать пока какойнидуть один не выйдет из какого нибудь одного блока).
Я использую синхронизацию по классу, чтобы организовать очередь обращений клоггеру — потоки получают временой штамп, строку и объект, пишеут в StringBuffer-ы, результат своей работы подают "на конвейер" в синхронный метод, который:
[ul]
[li]Пишет строку в файл.[/li]
[li]Пишет её в консоль[/li]
[li]Отправляет её в графический логгер (swing-компонент).[/li]
[/ul]
Если бы писать в файл например не каждый раз а 1-2 раза в секунду — это ускорит работу но об "ошибке перед крахом" инфа будет утерена...
Здравствуйте, aefimov, Вы писали:
A>Здравствуйте,
А>>1) Привильно ли я понимаю, что следующие два куска кода эквивалентны?
A>Нет. Синхронизация метода блокирует метод, синхронизация this блокирует инстанс объекта.
А>>2) Если я хочу положить ЧАСТЬ данных внутри функции класса под тотже мьютекс что и synchronized методах я могу использовать synchronized(this). Так?
A>Нет. Синхронизация происходит по средствам семафоров, в качестве которых выступают объекты JVM. Cинхронизация по this — это синхронизация по инстансу объекта класса. Именно эту синхронизацию не рекомендуется использовать, так как это блокирует доступ к объекту целиком (в синхронизированных участках кода этого объекта будет всего один тред, причем, если участков много, то это приведет к тому, что все треды будут ждать пока какойнидуть один не выйдет из какого нибудь одного блока).
процитировал Java Language Specification, в которой объясняется как на самом деле работают и должны работать synchronized методы. Я могу лишь дополнить его ответ цитатой из того же JLS:
8.4.3.6 synchronized Methods
These are the same locks that can be used by the synchronized statement (§14.18); thus, the code:
class Test {
int count;
synchronized void bump() { count++; }
static int classCount;
static synchronized void classBump() {
classCount++;
}
}
Если у тебя есть основания считать, что в реальности все работает не так как в описано спецификации, приведи пример, который демонстрирует эти расхождения.
Здравствуйте, aefimov, Вы писали:
A>Здравствуйте, A>Нет. Синхронизация метода блокирует метод, синхронизация this блокирует инстанс объекта.
полный бред!
8.4.3.6 synchronized Methods
A synchronized method acquires a lock (§17.1) before it executes. For a class (static) method, the lock associated with the Class object for the method's class is used. For an instance method, the lock associated with this (the object for which the method was invoked) is used.
These are the same locks that can be used by the synchronized statement (§14.18); thus, the code:
class Test {
int count;
synchronized void bump() { count++; }
static int classCount;
static synchronized void classBump() {
classCount++;
}
}
А>>2) Если я хочу положить ЧАСТЬ данных внутри функции класса под тотже мьютекс что и synchronized методах я могу использовать synchronized(this). Так?
A>Нет. Синхронизация происходит по средствам семафоров, в качестве которых выступают объекты JVM. Cинхронизация по this — это синхронизация по инстансу объекта класса. Именно эту синхронизацию не рекомендуется использовать, так как это блокирует доступ к объекту целиком (в синхронизированных участках кода этого объекта будет всего один тред, причем, если участков много, то это приведет к тому, что все треды будут ждать пока какойнидуть один не выйдет из какого нибудь одного блока).
Больший бред чем предыдущий трудно вообразить. Но это тоже бред. Кем не рекомендуется? Ссылки. А зачем тогда вобще нужна синхронизация? Правильно, чо бы гарантировать что к объекту (а следовательно и к к его аттрибутам)одновременно может иметь доступ только один поток.
A>Спасибо!
RTFM.
процитировал Java Language Specification, в которой объясняется как на самом деле работают и должны работать synchronized методы. Я могу лишь дополнить его ответ цитатой из того же JLS: D>Если у тебя есть основания считать, что в реальности все работает не так как в описано спецификации, приведи пример, который демонстрирует эти расхождения.
Да есть. В приведенных примерах они действительно эквиваленты, но что будет, если методов несколько? Об этом умолчивают, а синхронизация, тем не менее, работает уже по другому.
Другими словами, чтобы сделать синхронизацию полностью эквивалентной, нужно на каждый метод создавать специальный локер-объект, в том же контексте (статическом или нет):
private final Object fooLocker = new Object();
public synchronized void foo() {
}
public void fooTheSameSync() {
synchronized(fooLocker) {
}
}
private static final Object fooLocker = new Object();
public static synchronized void foo() {
}
public static void fooTheSameSync() {
synchronized(fooLocker) {
}
}
В вашем примере приведен один метод в классе, поэтому можно в этом конкретном случае синхронизировать единственный блок инстансом класса MyClass.class или ссылкой this. Однако, если вы будете делать тоже самое для других методов, то это заблокирует доступ к ним не так как при синхронизации методов:
public void foo1() {
syncronized (this) {
// Если мы тут, то ни один другой метод не вызывается
// Из других потоков
}
}
public void foo2() {
syncronized (this) {
// Если мы тут, то ни один другой метод не вызывается
// Из других потоков
}
}
Здравствуйте, Lucker, Вы писали:
L>Больший бред чем предыдущий трудно вообразить. Но это тоже бред. Кем не рекомендуется? Ссылки. А зачем тогда вобще нужна синхронизация? Правильно, чо бы гарантировать что к объекту (а следовательно и к к его аттрибутам)одновременно может иметь доступ только один поток.
И на том спасибо. Ну это вообщем то известная вещь, ну вот человек, который написал более чем 400 инспекций для IntelliJ IDEA, Dave Griphit:
Such blocks, like synchronized methods, make it hard to track just who is locking on a given object, and make possible "denial of service" attacks on objects.
И есть специальная инспекция по этому поводу, собственно. Но если так уж настаиваете могу найти "ссылок"...
Синхронизация нужна только лишь для того, чтобы быть уверенным, что в контексте одного треда данные актуальны. Блокировка — побочное явление, которое по возможности, нужно избегать.
По поводу вашего примера из JLS — я там в предыдущем постинге написал.
Здравствуйте, aefimov, Вы писали:
A>Другими словами, чтобы сделать синхронизацию полностью эквивалентной, нужно на каждый метод создавать специальный локер-объект, в том же A>контексте (статическом или нет):
A>Спасибо!
Еще раз!
Во-первых, метод помеченный как синхронизированный синхронизируется на объекте, которому он принадлежит, в случае instance метода (и т.д. по спецификации) а не на отдельном объекте для каждого такого метода.
Во-вторых, зачем синхронизировать доступ к отдельному методу? Синхронизация необходима для предотвращения одновременного доступа к объекту, что бы не нарушить инвариантность его состояния. Если для некоторого метода необходимо синхронизировать доступ к некоторому подможеству состояния объекта (читай подможеству атрибутов) нежели в остальных методах, имеет смысл подумать о "выделении класса"!
Здравствуйте, aefimov, Вы писали:
A>И на том спасибо. Ну это вообщем то известная вещь, ну вот человек, который написал более чем 400 инспекций для IntelliJ IDEA, Dave Griphit: A>Such blocks, like synchronized methods, make it hard to track just who is locking on a given object, and make possible "denial of service" attacks on objects. A>И есть специальная инспекция по этому поводу, собственно. Но если так уж настаиваете могу найти "ссылок"...
Ну во первых это всего лишь инспекция, которая ищет потенциальное место ошибок. Во вторых, цитируешь — цитируй полностью. А то смысл, как-то коряжется. Там написано что и synchronized(this) и synchronized метод могут привести к возникновению дедлоков. Если какой один левый поток захватит лок для такого объекта и не отпустит, что все потоки, входящие в блоки синхронизации на этом объекте окажутся заблокированы. Но ведь это не значит, что теперь необходимо отказаться от synchronized методов. Это значит, что надо просто грамотно работать с synchronized блоками.
A>Синхронизация нужна только лишь для того, чтобы быть уверенным, что в контексте одного треда данные актуальны.
Точно. То есть
1) ты при входе в synchronized блок имеешь актуальное состояние объекта (то есть состояние объекта в копии памяти потока эквивалентно состоянию объекта в глобальной копии памяти)
2) пока ты в synchronized блоке, никакой другой поток не нарушит состояние объекта в глобальной копии памяти.
3) при выходе из synchronized блока состояние объекта в глобальной копии памяти синхронизируется с состоянием объекта в локальной копии памяти потока.
A>Блокировка — побочное явление, которое по возможности, нужно избегать.
Когда синхронизируемое состояние объекта составляется из нескольких аттрибутов — блокировки не избежать.
A>И есть специальная инспекция по этому поводу, собственно. Но если так уж настаиваете могу найти "ссылок"...
не понял, на какую тему "ссылок"? что можно блокировать методы, а не объекты целиком?
A>Синхронизация нужна только лишь для того, чтобы быть уверенным, что в контексте одного треда данные актуальны.
теперь рассмотрим что происходит, если, как ты говоришь, блокировка накладывается только на один синхронизированный метод, а не на весь объект — дергаешь в потоке sync метод, и пока он выполняется другой метод из другого потока (по-твоему неважно уже sync метод или не sync, т.к. они не имеют отношения к блоку вызванного тобою метода) меняет данные объекта этого же объекта, т.е. данные для твоего потока становятся не актуальны. вывод допиши сам.
A>Спасибо!
Здравствуйте, Lucker, Вы писали:
L>Ну во первых это всего лишь инспекция, которая ищет потенциальное место ошибок. Во вторых, цитируешь — цитируй полностью. А то смысл, как-то коряжется. Там написано что и synchronized(this) и synchronized метод могут привести к возникновению дедлоков. Если какой один левый поток захватит лок для такого объекта и не отпустит, что все потоки, входящие в блоки синхронизации на этом объекте окажутся заблокированы. Но ведь это не значит, что теперь необходимо отказаться от synchronized методов. Это значит, что надо просто грамотно работать с synchronized блоками.
Здравствуйте, Волк-Призрак, Вы писали:
ВП>Ого! Вот это настоящие принципиальные отличия....
Извиняюсь, это я погорячился, походу дела я не прав, и все что ты написал действительно так и есть.
Проверили тут только что и оживленно проверили всей коммандой Короче, неправ был, исправлюсь
ВП>Я использую синхронизацию по классу, чтобы организовать очередь обращений клоггеру — потоки получают временой штамп, строку и объект, пишеут в StringBuffer-ы, результат своей работы подают "на конвейер" в синхронный метод, который: ВП>[ul] ВП>[li]Пишет строку в файл.[/li] ВП>[li]Пишет её в консоль[/li] ВП>[li]Отправляет её в графический логгер (swing-компонент).[/li] ВП>[/ul] ВП>Если бы писать в файл например не каждый раз а 1-2 раза в секунду — это ускорит работу но об "ошибке перед крахом" инфа будет утерена...
Яб наверное использовал апендеры для Log4J для этих целей... Но вообще, идея правильная. Только я, наверное, сделал бы тред отдельный который смотрит на очередь сообщений. Берет сообщение и все апендеры, последовательно передает сообщение каждому апендеру. А каждый апендер уже фигачит это куда ему хочеться — в базу, в файл и т.д. Ну сообственно Log4J так и работает.
Здравствуйте, Аноним, Вы писали:
А>теперь рассмотрим что происходит, если, как ты говоришь, блокировка накладывается только на один синхронизированный метод, а не на весь объект — дергаешь в потоке sync метод, и пока он выполняется другой метод из другого потока (по-твоему неважно уже sync метод или не sync, т.к. они не имеют отношения к блоку вызванного тобою метода) меняет данные объекта этого же объекта, т.е. данные для твоего потока становятся не актуальны. вывод допиши сам.
Да, фигня какаято Меня уже наставили на путь истинный... спасибо, чето я вчера погорячился.
Здравствуйте, aefimov, Вы писали:
ВП>>Я использую синхронизацию по классу, чтобы организовать очередь обращений клоггеру — потоки получают временой штамп, строку и объект, пишеут в StringBuffer-ы, результат своей работы подают "на конвейер" в синхронный метод, который: ВП>>[ul] ВП>>[li]Пишет строку в файл.[/li] ВП>>[li]Пишет её в консоль[/li] ВП>>[li]Отправляет её в графический логгер (swing-компонент).[/li] ВП>>[/ul] ВП>>Если бы писать в файл например не каждый раз а 1-2 раза в секунду — это ускорит работу но об "ошибке перед крахом" инфа будет утерена...
A>Яб наверное использовал апендеры для Log4J для этих целей... Но вообще, идея правильная. Только я, наверное, сделал бы тред отдельный который смотрит на очередь сообщений. Берет сообщение и все апендеры, последовательно передает сообщение каждому апендеру. А каждый апендер уже фигачит это куда ему хочеться — в базу, в файл и т.д. Ну сообственно Log4J так и работает.
Эээ.... А какая разница, очередь чего: сообщений в конвейере, или потоков к синхронному методу? А такая, что за явной очередью надо ухаживать, появляется промежуточный шаг (взять всю очередь), и мне думается, лучше пусть ось занимается синхронизацией, чем я