2009-12-03 5 views
0

У меня есть Java-апплет. Класс внутри этого апплета создает поток для выполнения некоторой работы, ожидая 30 секунд для завершения этой работы, если его не завершено за 30 секунд, он устанавливает логическое значение для остановки потока. Ожидание и изменение Boolean в синхронном блоке Является ли это необходимо, учитывая не существует никакой другой поток работает в стороне от этих 2.Требуется синхронизация

System.out.println("Begin Start Session"); 
    _sessionThread = new SessionThread(); 
    _sessionThread.start(); 

    synchronized (_sessionThread) 
    { 
     _sessionThread.wait(30000); 
     _sessionThread._stopStartSession = true; 
    } 

Почему я не мог просто сделать это вместо этого.

System.out.println("Begin Start Session"); 
    _sessionThread = new SessionThread(); 
    _sessionThread.start(); 

    _sessionThread.wait(30000); 
    _sessionThread._stopStartSession = true; 

SessionThread run method. Вызывает метод JNI для вызова DLL, чтобы открыть окно программы.

public void run() 
{ 
    try 
    { 
     startExtraSession(); 
    } 
    catch (Throwable t) 
    { 
     t.printStackTrace(); 
    } 
     notify(); 
} 


private native void openSessionWindow(String session_file); 

private void startExtraSession() 
{ 
    final String method_name = "startExtraSession"; 

    String title = _sessionInfo._title; 
    long hwnd = 0; 

    openSessionWindow(_sessionInfo._configFile); 

    try 
    { 
     //Look for a window with the predefined title name... 
     while ((hwnd = nativeFindWindow(title)) == 0 && !_stopStartSession) 
     { 
      Thread.sleep(500); 
    } 
    } 
    catch(Throwable t) 
    { 
     t.printStackTrace(); 
    } 
} 

1. Действительно ли синхронизирован?
2. Есть ли лучший способ сделать это, помимо использования потоков?

ответ

3

Данная ветка необходима для хранения блокировки объекта, чтобы иметь возможность называть wait(long). Это достигается за счет использования синхронизированного блока на указанном объекте.

См. J2SE specification при использовании wait.

Эквайринг стопорное/монитор в Java может быть сделано различными способами:

  • В (нестатической) метод synchronized, поток владеет монитора на объект, на который ссылается this.
  • В методе static synchronized поток владеет монитором в дескрипторе Class<?> для класса, который определяет указанный метод.
  • В блоке synchronized(x) нить владеет монитором на x.

что блокировка будет освобождено, если:

  • Вы получаете за пределами синхронизированного блока кода (будь то метод, статический метод, или явный блок).
  • Вы вызвали wait() или один из его вариантов (и вы повторно приобретете его непосредственно перед возвратом метода).

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

+0

Если поток принадлежит классу, с которого он звонит в синхронный раздел, не соответствует ли это требованиям? Прошло много времени с моих дней Java, поэтому, пожалуйста, просветите меня. –

+0

Если вы находитесь вне любого синхронизированного метода или любого синхронизированного блока, вы не являетесь владельцем какого-либо монитора и, следовательно, не можете называть 'wait'. Позвольте мне отредактировать мой ответ, чтобы быть более четким при сборе блокировки/монитора. – Romain

0

Не могли бы вы опубликовать SessionThread код? Вы не можете дождаться, если вы не владеете блокировкой, поэтому вам нужно синхронизировать (_sessionThread), чтобы выполнить _sessionThread.wait (30000); Не уверен, что с _sessionThread._stopStartSession = true;

+0

Я предполагаю, что boolean убивает цикл во втором потоке. –

+0

Да, если 2-й поток работает дольше 30 секунд, время будет ломаться при изменении логических значений. Также добавлен другой код – Keibosh

1

Там очень простой причине, что вам нужно synchronized позвонить wait

В synchronized убеждается, что никто не звонит notify или notifyAll в то же время вы звоните wait

Например: Thread 1

synchronized(obj) 
{ 
    triggerActionOnThread2(); 
    obj.wait(); 
} 

резьбы 2 (запускается triggerActionOnThread2)

... 
    synchronized(obj) 
    { 
     obj.notify(); 
    } 

Если у вас нет синхронизированных блоков, то notify может произойти до (или во время) в wait, а затем wait пропускает notify, и вы можете повесить Тема 1.

Представьте себе над блоками кода без блоков synchronized, и представьте, если Thread 2 выполняется полностью через уведомление перед вызовом wait.

Кстати, я задаю этот вопрос на собеседовании для инженеров-Java, когда работа будет включать многопоточное программирование.

+0

Кажется, что синхронизация предназначена для конкретной цели, когда есть исключение? –

+0

Не совсем. Синхронизация заключается в обеспечении правильного порядка. wait/notify - это в основном семафор. Вы хотите, чтобы один поток ожидал первый, а другой поток уведомлял второй. – karoberts

+0

Я имел в виду в приведенном примере. Но, посмотрев на это снова, уведомление() будет ПОСЛЕ попытки/улова. Спасибо за ваш вклад (или это ваш выход?)! –

0

Если логическое состояние является единственным разделяемым состоянием между потоками, объявление булевского переходного процесса гарантирует, что изменения в нем будут видны между потоками, а также блок синхронизации вокруг доступа к булевому.

Смежные вопросы