2014-08-12 3 views
0

Да, я видел предыдущие вопросы по подобным темам, но они, похоже, не помогают мне. Если есть дубликат, пожалуйста, укажите мне на вопрос, спасибоIllegalMonitorStateException: объект не заблокирован нитью до уведомления()

У меня есть две проблемы здесь, то первый из них является титульный проблема:

@Override 
protected void onCreate(Bundle savedInstanceState){ 
    super.onCreate(savedInstanceState); 
//Starts up method1 & method2 in a try-catch 
    try{ 
     method1(); 
     method2(); 
     new CountDownLatch(1); 
     CountDownLatch.await(); 
    }catch(InterruptedException e){ 
     // TODO Auto-generated catch 
     // block 
     e.printStackTrace(); 
    } 
//This Toast should only run after notify() is called 
    Toast.makeText(firstClass.this, "This is toasty", Toast.LENGTH_SHORT).show(); 
} 


//Start of method 1, which is currently useless 
public void method1() throws InterruptedException{ 
//Creates new thread 
    Thread thread = new Thread(new Runnable(){ 
     @Override 
     public void run(){ 
      try{ 
       synchronized(SecondClass.this){ 
       } 
      }catch(Exception e){ 
       e.printStackTrace(); 
      } 
     } 

    }); 
    thread.start(); 
} 

public void method2(){ 
    Thread thread2 = new Thread(new Runnable(){ 
     @Override 
     public void run(){ 

//Sets a button, when the button is clicked, then the code is continued 
       final Button bNext = (Button) findViewById(R.id.bIsoAbunSave); 
       bNext.setOnClickListener(new OnClickListener(){ 
        @Override 
        public void onClick(View arg0){ 
         synchronized(SecondClass.this){ 
         CountDownLatch.countDown(); 
         } 
        } 
       }); 
      } 


    }); 
    thread2.start(); 
} 

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

Вторая проблема еще до того, как я нажму кнопку, появится Toast. Я предположил, что когда я вызвал wait(), весь код подождал, пока я не нажал кнопку, где будет вызываться notify(), и код будет продолжен. Но вместо этого происходит то, что Toast, по-видимому, игнорирует wait() и работает в любом случае.

Если у вас есть какие-либо вопросы, пожалуйста, спрашивайте, спасибо.

EDIT: Сообщение LogCat показывает, что авария происходит на:

synchronized(SecondClass.this){notify();} 
+0

«Вторая проблема еще до того, как я нажму кнопку, появляется тост. Я предположил, что когда я позвоню wait(), весь код будет ждать, пока я не нажму кнопку, где будет вызываться notify(), и код будет но вместо этого происходит то, что тост, по-видимому, игнорирует wait() и работает в любом случае ». это потому, что у вас есть 3 потока в коде, один поток пользовательского интерфейса, который продолжает выполнение, и 2 разных потока, которые вы создали, поток пользовательского интерфейса перескакивает с создания потоков и продолжается так, что он сталкивается с вашим тостом !!! – mmlooloo

+1

"что wait() делает это, останавливает весь текущий код" Не уверен, что вы подразумеваете под _all_ running code. Что делает 'foo.wait()' is is, он освобождает монитор для foo, он ждет уведомления, он повторно приобретает монитор для foo, а затем возвращается. Он не «останавливает» какой-либо другой поток. –

ответ

1

Здесь

synchronized(this){ 
//Sets a button, when the button is clicked, then the code is continued 
      final Button bNext = (Button) findViewById(R.id.bIsoAbunSave); 
      bNext.setOnClickListener(new OnClickListener(){ 
       @Override 
       public void onClick(View arg0){ 
        notify(); 
       } 
      }); 
} 

Вы заблокировать вызов findViewById и setOnClickListener, но не метод OnClick, поэтому при вызове notify находится вне любого синхронизированного блока.

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

//Sets a button, when the button is clicked, then the code is continued 
      final Button bNext = (Button) findViewById(R.id.bIsoAbunSave); 
      bNext.setOnClickListener(new OnClickListener(){ 
       @Override 
       public void onClick(View arg0){ 
        synchronized(TopClass.this){ notify(); } 
       } 
      }); 

(запомнить this отличается внутренним классом)

Во всяком случае использование wait/notify не рекомендуется, рассмотрите возможность использования одного из других многопоточных классов и коллекций в JDK.


synchronized(this){ 
    //These statements *should* make the code wait until I click the button 
    wait(); 
} 

Здесь syncronizate Runnable не основной класс.

+0

Я изменил код, но ошибка все еще происходит. Я только что изменил «это» на «SecondClass.this» (который является классом, в котором находится код), но сообщение об ошибке все еще существует. – user154989

+0

Какое сообщение об ошибке? –

+0

Сообщение об ошибке заголовка – user154989

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