Timer.wait() - java.lang.IllegalMonitorStateException

0

Cześć, co prawda problem jest wytłumaczony na StackOverflow jednak przykłady tam zawarte są dla mnie zbyt skomplikowane i nie mogę na ich podstawie zrozumieć problemu.

A problem przedstawia się następująco - t.wait() za każdym razem rzuca wyjątek java.lang.IllegalMonitorStateException. Czy ktoś mógłby powiedzieć mi jak to na prawić i przede wszystkim - dlaczego tak się dzieje i jak uniknąć tego typu błędów w przyszłości? Poniżej zamieszczam kluczową część kodu, jeżeli zajdzie taka potrzeba zamieszczę całą resztę. Z góry dziękuję!

  public class ColorAction implements ActionListener
        {      
                public ColorAction(Color c, Color d, Color e)
                {
                        bgc1 = c;
                        bgc2 = d;
                        bgc3 = e;
                }
               
                public void actionPerformed(ActionEvent event)
                {
                	Timer t = new Timer();
                	for (int i=0; i<1000; i++)
                		{
                			try
                			{
                				buttonPanel.setBackground(bgc1);
                				t.wait(60);
                				buttonPanel.setBackground(bgc2);
                				t.wait(60);
                				buttonPanel.setBackground(bgc3);
                				t.wait(60);
                			}
                			catch (InterruptedException x)
                			{
                				buttonPanel.setBackground(Color.BLACK);
                				System.out.println(x);
                			}
                		
                		}
                }
       
                private Color bgc1, bgc2, bgc3;
        }
1

blok musi byc synchronizowany

z oracla:

. When a thread invokes d.wait, it must own the intrinsic lock for d — otherwise an error is thrown. Invoking wait inside a synchronized method is a simple way to acquire the intrinsic lock.

0

W skrócie: nie umiesz czytać. Mylisz Thread.sleep() z Object.wait(). Te dwie metody robią TOTALNIE co innego.

0
Shalom napisał(a):

W skrócie: nie umiesz czytać. Mylisz Thread.sleep() z Object.wait(). Te dwie metody robią TOTALNIE co innego.

Nie rozumiem Twojej agresii, jeżeli nie chciałeś pomóc to dlaczego odpowiadałeś? A koledze wyżej dziękuję serdecznie za pomoc :)

0

@niezdecydowany technicznie rzecz biorąc tak, ale problem leży w tym że autor używa złej metody która robi zupełnie co innego niż mu się wydaje.
@Skyler brawo, tylko że to co robisz jest po prostu błędem.

0
Shalom napisał(a):

@Skyler brawo, tylko że to co robisz jest po prostu błędem.

Nie pierwszym i nie ostatnim, przecież dopiero się uczę :). Mógłbyś mi wytłumaczyć w czym leży błąd? W jaki inny sposób powinienem rozwiązać problem?

1

Ech. Uśpienie wątku na pewien czas osiąga sie za pomocą Thread.sleep(). Object.wait() to metoda stosowana do niskopoziomowej synchronizacji wątków. wait() oznacza dość skomplikowany zestaw czynności:

  • aktualny wątek jest stopowany
  • monitor danego obiektu jest zwalniany (więc inne wątki czekające na dostęp do danego obiektu mogą go teraz uzyskać)
  • aktualny wątek czeka na "odmrożenie" za pomocą notify() od wątku który dostanie monitor
  • ewentualnie wait ma parametr timeout który pozwala na powrót do życia tego wątku, jeśli nikt nie zawołał notify przez okreslony czas

Generalnie wait() to jest coś do synchronizacji między wątkami, a nie do spowalaniania aplikacji...

0

Dziękuję!

1 użytkowników online, w tym zalogowanych: 0, gości: 1