Miksi seuraava säie lakkaa toimimasta kun ikkunan pienentää ja sen jälkeen suurentaa takaisin? Start-metodissa tulee illegalthreadstateexception ja jos sen käsittelee tekemättä mitään, run-metodia ei kutsuta ikinä
private class Säie extends Thread
{
private boolean lopeta = false;
Säie()
{
}
public void start()
{
super.start();
}
public void run()
{
lopeta = false;
while(!lopeta)
{
try
{
// Tee sälää täällä
}
catch(InterruptedException e)
{
quit();
}
}
}
// tätä kutsumalla säie päättyy
public void quit()
{
lopeta = true;
}
};
}
private class Säie extends Thread
{
private boolean lopeta = false;
Säie()
{
}
public void start()
{
super.start();
}
public void run()
{
lopeta = false;
while(!lopeta)
{
try
{
// Tee sälää täällä
}
catch(InterruptedException e)
{
quit();
}
}
}
// tätä kutsumalla säie päättyy
public void quit()
{
lopeta = true;
}
};
}
Vastaukset 5
Vanhimmat
1. Pistä konstruktoriin super(), helpottaa koodin lukemista (ja ehkä ratkaisee ongelmasi).
2. Et tarvitse omaa start-metodia, sillä sehän on super-luokassa jo toteutettu.
3. Pistä edes pieni sleep run-metodin silmukkaan. Muuten silmukka vie "kaiken" ajan. Tietty sleep voi olla "sälän" mukana, mutta itse pistän sen olennaisena osana silmukan loppuun tai alkuun. Joskus jopa lasken sälän suorittamiseen kuluvan ajan, ja sleeppaan vain jos on tarvetta.
Vastaus: ehkäpä silmukassa tehtävä sälä on blokkaavaa, ja blokkaavan operaation suorittaminen taas on suhteessa ikkunan näkymiseen.
IllegalThreadStateException tulee, kun threadiä yrittää pakottaa tilasta toiseen, "laittomaan tilaan". Esim jos threadi on sammunut, sitä ei saa enää käyntiin...
> 1. Pistä konstruktoriin super(), helpottaa koodin
> lukemista (ja ehkä ratkaisee ongelmasi).
Tällä ei ole mitään vaikutusta mihinkään, super()-konstruktoria kutsutaan aina ennen luokan oman konstruktorin suorittamista. Paitsi silloin, jos yliluokalla ei ole parametritonta konstruktoria, jolloin sitä pitää kutsua itse tai kääntäjä palauttaa virheen.
> 3. Pistä edes pieni sleep run-metodin
> silmukkaan. Muuten silmukka vie "kaiken" ajan.
> Tietty sleep voi olla "sälän" mukana, mutta itse
> pistän sen olennaisena osana silmukan loppuun
> tai alkuun. Joskus jopa lasken sälän
> suorittamiseen kuluvan ajan, ja sleeppaan vain
> jos on tarvetta.
No, sleep-metodia käytetään silloin kun siihen on tarvetta. Ei sitä pidä mitenkään oletuksena tonne tunkea. Voihan säie sälä-osuudessa esim. kutsua omaa quit-metodiaan ja lopettaa yhden kierroksen jälkeen.
Alkuperäiseen vastauksena: poista kutsu quit()-metodiin catch-lauseesta. Saattaa olla, että ikkunan näkyvyys/näkymättömyys aiheuttaa tuon InterruptedExceptioinin ja quit-metodin jälkeen et enää tee säikeellä mitään, kun se on lopettanut (tuottaa IllegalThreadStateExceptionin)
"super()-konstruktoria kutsutaan aina ennen luokan oman konstruktorin suorittamista"
Noh, näinhän se speksin mukaan menee. Siis kääntäjä lisää super()-konstruktorin, jos sitä ei ole. Itse asiassa Säie-luokan konstruktoria ei tarvittaisi ollenkaan, sillä kääntäjä lisää (pitäisi lisätä) senkin automaattisesti.
"Ei sitä pidä mitenkään oletuksena tonne tunkea."
Mmh, säie joka pyörii loputtomassa loopissa vieden kaiken ajan... Ehdottomasti kannattaa antaa aikaa myös muille säikeille.
> Mmh, säie joka pyörii loputtomassa loopissa vieden
> kaiken ajan... Ehdottomasti kannattaa antaa aikaa
> myös muille säikeille.
Esimerkkikoodistahan tätä ei voi päätellä, kun siinä ei näytetty mitä loopissa oikeasti tehdään. Ylipäätään busy-loopin tekemisessä on harvoin mitään järkeä. Jos säie pyörii loopissa päättömästi, kannattaa miettiä tarvitaanko säiettä ollenkaan, tai pitäisikö säikeen suoritusta synkronoida jotenkin. Satunnaisten sleep-kutsujen lisääminen kielii IMHO ohjelman huonosta suunnittelusta.
Start metodi palauttaa IllegalThreadStateException -poikkeutuksen, kun säie on jo käynnissä. Eli todennäköisesti yrität käynnistää säiettä toistamiseen. Milloin tai missä kutsut, tai mikä laukaisee start -metodin?
Oletko tekemässä swing sovellusta, vai tarkoititko ihan normaalia konsoli ikkunaa?