2013-05-08 6 views
1

Я новичок в теме синхронизации, и я не мог найти четкую информацию в любом месте об использовании методов wait(), notify() и notifyAll() при попытке доступа к синхронизированному объекту. Для exmaple, если у нас есть такой код:Синхронизация данных между многими потоками

class X extends Thread { 
    int x; 

    public void methodX() 
    { 
     synchronized(this) 
     { 
      //some operations on x 
     } 
    } 
} 

class Y extends Thread { 
    public void methodY(X x) 
    { 
     int z = x.x; 
    } 
} 

Если мы называем wait() в methodY() и notify() в конце methodX()? В противном случае мы не будем присваивать какое-либо значение z или поток будет ждать без явного вызова wait() до тех пор, пока X не разблокирует?

+0

Что вы пытаетесь сделать? Включить main() –

+2

Нет, не стоит. Поскольку X.x обращается к нескольким потокам, каждый доступ должен просто синхронизироваться на одном объекте. Прочтите [Java-учебник по параллелизму] (http://docs.oracle.com/javase/tutorial/essential/concurrency/) и Java Concurrency на практике от Брайана Гетца. Также прочитайте javadoc wait() и уведомите(), чтобы узнать, какова их цель и использование. –

+0

Некоторое разъяснение, пожалуйста ... является ли ваше требование о том, что присвоение 'method'' z' должно происходить только после выполнения 'methodX'? –

ответ

2

Так дайте, что вам нужно methodY ждать, пока methodX не выполнил, один действительный способ сделать это wait и notify или notifyAll. Есть, конечно, несколько других способов, но это действительно. Учитывая, что вам может даже не понадобиться синхронизированный блок.

void methodX(){ 
     // do your work here 
     this.notifyAll(); 
} 

void methodY(X x){ 
    x.wait(); 
    int x = X.x; 
} 

Вы могли бы рассмотреть вопрос о создании кода блокировки в методе getX в X но выше будет работать, если (и это BIG IF) вы можете гарантировать, что methodY начинается до того methodX, потому что в противном случае methodY пропустит notify вызов ,

Все вышеперечисленное, я согласен с JB Nizet, вы можете рассмотреть более высокоуровневый механизм, такой как Семафор/Мьютекс/и т. Д. Это облегчает сложность. Например, если вы используете CountDownLatch и создать его с числом 1 кода, вероятно, будет более надежной ...

Рассмотрим:

class X{ 
    volatile int x; 
    final CountDownLatch cdl = new CountDownLatch(1); 

    void methodX(){ 
     // do work here 
     cdl.countDown(); 
    } 

    int getX(){ 
     cdl.await(); 
     return x; 
    } 
} 

class Y{ 
    void methodY(X x){ 
     int z = X.getX(); 
    } 
} 

выше будет работать каждый раз, когда без каких-либо рисков заказа.

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