2013-06-01 4 views
2

У меня есть 2 темы в моей программе следующим образом:Thread Синхронизация

class SendThread implements Runnable { 
    public void run(){ 
      Thread.sleep(1000); 

      while (true){  
       if (CONNECTION_ESTABLISHED){ 
        // code here 
       } 
      } 
    } 
} 

class ReceiveThread implements Runnable { 
    public void run(){ 


      while (true){  
       // code here 
       CONNECTION_ESTABLISHED = true; 

      } 
    } 
} 

Я определил CONNECTION_ESTABLISHED как static Boolean.

Во второй резьбе BooleanCONNECTION_ESTABLISHED установлен в true в определенный момент. Если я не использую Thread.sleep(1000) в 1-й строке, после того, как CONNECTION_ESTABLISHED установлено в true во 2-м потоке, я не вношу соответствующий if оператор в 1-й поток.

Есть ли другой способ обойти это? Потому что мой 1-й поток часто зависит от переменных изменений во втором потоке.

+0

Благодарим за редактирование этого Мартина. Как помещать переменные в этот серый квадрат, как вы? –

ответ

1

Добавить volatile ключевое слово CONNECTION_ESTABLISHED метод и посмотреть.

+0

Спасибо Тихаре, что, похоже, сработало. –

0

Вы столкнулись с проблемой, потому что вы изменяете статическую переменную CONNECTION_ESTABLISHED несинхронизированным образом, и вы не используете механизм уведомления о ожидании связи потоков. Использование wait wait должно помочь вам. Создайте объект, который будет использоваться для ожидания-уведомление и использовать код, как показано ниже

class SendThread implements Runnable { 
    public void run(){ 
      Thread.sleep(1000); 

      while (true){ 
       synchronized(object) { 
        object.wait(); 
        if (CONNECTION_ESTABLISHED){ 
         // code here 

        } 
       } 
      } 
    } 
} 

class ReceiveThread implements Runnable { 
    public void run(){ 


      while (true){ 
       synchronized(object) { 
        // code here 
        CONNECTION_ESTABLISHED = true; 
        object.notify(); 
        } 
      } 
    } 
} 

Я не проверял код, я просто пытался поставить понятие так вносить изменения по мере необходимости.

0

В этом конкретном примере вы можете пометить логическое CONNECTION_ESTABLISHED как volatile, и оно будет работать как ожидалось, другие потоки будут видеть изменение при следующем доступе к переменной.

Однако я предостерег вас от использования volatile для чего угодно, кроме самых простых случаев (одно обновление переменной). Он не содержит атомарности, поэтому, если вам нужно выполнить больше одного задания во время обновления, он не предоставит необходимые гарантии. Это включает в себя приращения/декременты, которые на самом деле являются 3 операциями, чтение/изменение/запись на уровне модели памяти, поэтому требуется правильная синхронизация.

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

private final Object lock = new Object(); 

private int shared1; 
private int shared2; 

public void write(int var1, int var2) 
{ 
    sychronized (lock) 
    { 
    shared1 = var1; 
    shared2 = var2; 
    } 
} 

public int readSum() 
{ 
    sychronized (lock) 
    { 
    int total = shared1 + shared2; 
    return total; 
    } 
} 
+0

Спасибо за то, что Майк. Ваша точка должным образом отмечена. Я начал читать об этом. –

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