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

Я имею дело с состоянием гонки, я полагаю, в моем JAVA GUI.

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

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

               //stuff

          }
     };
}

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

ВОПРОС2: если бы я избавился от "synchronized" в объявлении run() и вместо этого имел блок synchronized(this) {} внутри тела run(), "this" будет ссылаться на объект TimerTask или на объект, который такое экземпляр метода, который содержит foo()?

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

Спасибо jbu

4 ответа

Решение

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

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

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

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

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

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

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

  пытаться {
            SwingUtilities.invokeAndWait(new Runnable(){
                public void run(){
                    Swing_Prozor1 prozor = new Swing_Prozor1();
                }
            });
        } catch (InterruptedException e) {
            // намерно занемарено
        } catch (InvocationTargetException e) {
            // намерно занемарено
        }

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

ClassName.this

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

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

окончательная блокировка объекта = новый объект ();

а затем синхронизировать на нем.

foo() {
    synchronized(lock) {
       someMethod(new TimerTask() {
          public void run() {
              synchronized(lock)  {
                     //stuff
              }
          }
      }
Другие вопросы по тегам