Подтвердить что ты не робот

Java анонимные классы и синхронизация и "this"

В моем JAVA GUI я имею дело с состоянием гонки.

У меня есть некоторые методы, которые создают "анонимный метод" внутри анонимного класса следующим образом:

synchronized foo()
{
     someMethod(new TimerTask()
     {
          public synchronized run()
          {

               //stuff

          }
     };
}

ВОПРОС: это метод запуска, синхронизированный с объектом TimerTask или классом, в котором находится foo?

QUESTION2: если бы я избавился от "синхронизированного" в объявлении run() и вместо этого имел синхронизированный (этот) {} блок внутри тела run(), "this" ссылался бы на объект TimerTask или на объект, являющийся экземпляром метода, который содержит foo()?

Пожалуйста, помогите мне здесь.

Спасибо, JBU

4b9b3361

Ответ 1

Метод run синхронизируется по самому TimerTask. Синхронные методы всегда синхронизируются по объекту this. (Методы класса синхронизируются по объекту Class.)

Если вы хотите синхронизировать объект, членом которого является foo, вам необходимо присвоить ключевое слово this. Предположим, foo() является членом класса Bar, внутри метода run() TimerTask, вы можете использовать

public void run() {
  synchronized(Bar.this) {
    ...
  }
}

Ответ 2

Я уверен в этих ответах, но я не могу выкопать хороший источник.

Первый вопрос:
синхронизированный будет блокировать TimerTask.

Второй вопрос:
это относится к TimerTask; если вы хотите заблокировать содержащий объект, вы должны использовать MyContainingObject.this

Ответ 3

Существует только один поток, который может иметь доступ к элементам качания. Thats AWT-EventQueue-0. Вы должны знать об этом. Если другие ваши нити дрожат или меняют элементы, существует очень большая вероятность того, что gui выйдет из строя. Чтобы запустить ваш gui с помощью этого потока:

  try {
            SwingUtilities.invokeAndWait(new Runnable(){
                public void run(){
                    Swing_Prozor1 prozor = new Swing_Prozor1();
                }
            });
        } catch (InterruptedException e) {
            //namjerno zanemareno
        } catch (InvocationTargetException e) {
            //namjerno zanemareno
        }

и если у вас есть классы анонимуса, это даст вам экземпляр класса, в котором вы находитесь, поэтому, если вы пишете в классе anonymus это. является экземпляром этого класса. Чтобы получить экземпляр класса, который вы хотите написать:

ClassName.this

hmm этот выше код, который вы написали, говорит мне об этом. Вы дважды обрабатывали часть кода. Когда вы пишете синхронный метод, это означает, что только один поток может получить доступ к этому методу за один раз. Другие потоки ждут, пока синхронный метод разблокирован.

Ответ 4

Если вы ищете синхронизацию foo() и run(), вы можете создать явный объект блокировки, например

final Object lock = new Object();

а затем синхронизируйте его.

foo() {
    synchronized(lock) {
       someMethod(new TimerTask() {
          public void run() {
              synchronized(lock)  {
                     //stuff
              }
          }
      }