2010-09-04 3 views
2

Я не знаю про нить конфайнмент. В качели все компоненты gui должны обновляться через EDT. SwingWorker предоставляется в Java6 для длительных операций, а в готовом методе компоненты gui могут быть обновлены. Я понимаю, что компоненты gui в методе done() обновляются в EDT. Поэтому проблем с синхронизацией не должно быть. Но здесь link textОграничители резьбы/swingworkers

он говорит:

Поскольку класс ImageRetriever будет загрузить изображение и поместите его на большой наклейке, обеспечивая метку и URL изображения в конструкторе удобно. Для получения изображения ImageRetriever требуется URL-адрес . Предоставьте метку , чтобы экземпляр ImageRetriever мог установить значок метки . Если вы используете внутренние классы, вы можете указать информацию в конструкторе , потому что рабочий поток сможет получить доступ к информации напрямую. Однако предоставление информации в конструктор помогает вашему приложению быть более потокобезопасной, потому что информация не будет передаваться среди ImageRetriever экземпляров

Я запутался об этом. Если методы SwingWorker обновляют компоненты gui (в примере ссылки JLabel) в EDT, почему более потокобезопасно не делиться ими среди экземпляров ImageRetriever (= SwingWorker)? Если у нас есть несколько SwingWorkers, а в методе done() они обновляют один и тот же компонент, мы должны использовать примитивы синхронизации для обновления? Я что-то пропустил? Не означает ли ограничение потока, что только 1 поток выполнит все действия? Разве свингеры не связаны нитью?

Благодаря

ответ

1

Если метка объявлена ​​в родительском классе и по какой-то причине, новое значение присваивается этой переменной в некоторой точке, то все swingworkers будет видеть обновление. Поскольку это может произойти, когда EDT обновляет вещи, это может привести к странным поведением.

Например:

SW in EDT - label.setText(...); 
Thread1 - label = new JLabel(); 
SW in EDT - label.setIcon(...); 

Если переменная метка совместно вы получите несогласованное состояние (ярлык без текста или значок).

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

Если вы используете внутренние классы и атрибут родительского класса это будет выглядеть следующим образом:

public void done() { 
    JLabel l = label; 
    l.setText(...); 
    l.setIcon(...); 
} 

Если переменная определяется как атрибут SW, вам придется создать какой-то способ получения значение, хранящееся в основном классе (например, геттер)

+0

Но в вашем примере доступ к метке осуществляется нитью вне EDT, которая недопустима.Если в вашем примере отсутствовала вторая строка (Thread1 - label = new JLabel();) и у нас было SW в EDT - label.setText (...); SW в EDT - label.setText (...); - это поточно-безопасный. Моя проблема касается Jtree, но не так просто, как метка – Cratylus

+0

Запрещается вызывать методы на компонентах вне EDT, но допускается присвоение переменной. Да, он был бы потокобезопасным, если никакая другая операция не выполняется на компоненте (без Thread1). – Guillaume

+0

Последний вопрос. Если я передам jlabel в конструкторе SW, то любое изменение, сделанное Thread1, не будет отражено в методе SW done(). Правильно? Я имею в виду, что у SW будет ссылка на метку, а thread1 сделает метку на другой метке, но SW будет иметь старое значение. Как мне пойти, чтобы убедиться, что переменные, переданные в конструкторе, если они изменены, в EDT мы используем новое значение? Если у меня есть переменная String, которая имеет значение «A» перед вызовом SW.execute(); и после вызова execute переменная имеет значение «B», как это будет видно в done()? – Cratylus