анонимные классы Java, синхронизация и «это»
-
03-07-2019 - |
Вопрос
Полагаю, я имею дело с состоянием гонки в моем графическом интерфейсе JAVA.
У меня есть несколько методов, которые создают «анонимный метод» внутри анонимного класса, например:
synchronized foo()
{
someMethod(new TimerTask()
{
public synchronized run()
{
//stuff
}
};
}
ВОПРОС:синхронизирован ли этот метод запуска с объектом TimerTask или с классом, в котором находится foo?
ВОПРОС 2:если бы я избавился от слова «synchronized» в объявлении run() и вместо этого имел бы блок Synchronized(this) {} внутри тела run(), будет ли «this» относиться к объекту TimerTask или к объекту, который является экземпляр метода, который содержит foo()?
Пожалуйста, помогите мне здесь.
Спасибо, JBU
Решение
А run
метод синхронизируется на TimerTask
сам.Синхронизировано методы экземпляра всегда синхронизировано this
объект.(Методы класса синхронизируются на Class
объект.)
Если вы хотите синхронизироваться на объекте которого foo
являетесь участником, вам необходимо квалифицировать this
ключевое слово. Предполагать foo()
является членом Bar
класс, внутри run()
метод TimerTask
, вы можете использовать
public void run() {
synchronized(Bar.this) {
...
}
}
Другие советы
Я почти уверен в этих ответах, но не могу найти хороший источник.
Первый вопрос:
синхронизировано заблокирует TimerTask.
Второй вопрос:
это относится к TimerTask;если вы хотите заблокировать содержащий объект, вы должны использовать MyContainingObject.this
Существует только один поток, который может иметь доступ к элементам Swing.Это AWT-EventQueue-0.Вы должны знать об этом.Если другие ваши потоки перемещают или меняют элементы, очень велика вероятность того, что графический интерфейс выйдет из строя.Чтобы запустить ваш графический интерфейс с помощью этого потока:
try { SwingUtilities.invokeAndWait(new Runnable(){ public void run(){ Swing_Prozor1 prozor = new Swing_Prozor1(); } }); } catch (InterruptedException e) { //namjerno zanemareno } catch (InvocationTargetException e) { //namjerno zanemareno }
и если у вас есть анонимные классы, это даст вам экземпляр класса, в котором вы находитесь, поэтому, если вы пишете в анонимном классе, это.является экземпляром этого класса.Чтобы получить экземпляр класса, который вы хотите, напишите:
ИмяКласса.this
хм, приведенный выше код говорит мне об этом.Вы дважды защитили часть кода.Когда вы пишете синхронизированный метод, это означает, что только один поток может одновременно получить доступ к этому методу.Другие потоки ждут, пока синхронизированный метод будет разблокирован.
Если вы ищете синхронизацию foo() и run(), вы можете создать явный объект блокировки, например
окончательная блокировка объекта = новый объект();
а затем синхронизироваться на нем.
foo() {
synchronized(lock) {
someMethod(new TimerTask() {
public void run() {
synchronized(lock) {
//stuff
}
}
}