webForumDet fria alternativet

Trådfunderingar

8 svar · 328 visningar · startad av andreascarlsson

andreascarlssonMedlem sedan feb. 2003211 inlägg
#1
spangoMedlem sedan juni 20006 147 inlägg
#2

Att försäkra sig att det bara finns en instans av en klass är enkelt, man tillgriper bara designmönstret singleton:

class MailSender extends Vadsomhelst{
    private static MailSender instance;
    private MailSender(){} // privat konstruktor kan ej anropas utifrån
    public static synchronized MailSender getInstance() {
        if (instance == null) instance = new MailSender();
        return instance;
    }
}

Naturligtvis hindrar inte detta att två olika instanser av programmet skapar egna trådar. För att förhindra detta blir det betydligt bökigare, kan inte komma på något snyggt sätt att lösa det på. Eventuellt kan du använda fillåsning, men jag har dålig koll på hur det funkar i Java.

Det "säkraste" sättet att försäkra sig om att en tråd inte dör är att fånga alla Throwable som kastas inuti trådens run-metod. Kom bara ihåg att logga dessa undantag, annars kan du få ett par helgers bisarr felsökning på dina händer.

andreascarlssonMedlem sedan feb. 2003211 inlägg
#3

Ok! Tack för hjälpen...

Jag har funderat och klurat lite nu och jag tror att jag använder mig av java.util.Timer i en klass som använder designmönstret singleton (som Spango föreslog).

M.h.a. ett cronjob så hämtar jag bara klassens instans (enligt Spangos exempel) samtidigt som jag kör igång trådarna. Detta borde ju innebära att om trådarna redan lever, så händer inget, men om de inte lever, så startas de?

D.v.s.:

class TimerMonitor extends Vadsomhelst{
    private static TimerMonitor instance;
    private TimerMonitor(){} // privat konstruktor 
    public static synchronized TimerMonitor getInstance() {
        if (instance == null)
       {
            instance = new TimerMonitor();
            Timer timer1 = new Timer(...);
            Timer timer2 = new Timer(...);
        }
        return instance;
    }
}

Cronjobbet är sedan bara ansvarig för att att köra TimerMonitor.getInstance();

Vad tror ni om detta??

spangoMedlem sedan juni 20006 147 inlägg
#4

Det beror på hur det funkar... Men vad är det cronjobbet kontrollerar, egentligen? Att det returneras något från getInstance? Det är ingen garanti för att tråden rullar. Och hur kollar den vad som returneras?

andreascarlssonMedlem sedan feb. 2003211 inlägg
#5

Hrrmm... Mitt fel! Naturligtvis skall inget returneras till cronjobbet. Cronjobbet skall bara köras för att se till att processerna alltid lever. Med processer menar jag instanser av java.util.Timer

Förmodligen borde det se ut ungefär så här istället:

class TimerMonitor extends Vadsomhelst{
    private static boolean isAlive = false;
    private TimerMonitor(){} // privat konstruktor 
    public static synchronized void keepAliveAction() {
        if (isAlive == false)
        {
            isAlive = true;
            Timer timer1 = new Timer(...);
            Timer timer2 = new Timer(...);
        }
    }
}

Cronjobbet är tänkt att köras var 10:e minut (eller något liknande). Om applikationen (det är en webbapplikation) skulle gå ner/startas om, ser cronjobbet till att processerna (java.util.Timer-instanserna) startas upp igen. Om processerna redan lever, händer inget.

Är jag ute och cyklar nu, eller är detta ett hyfsat bra sätt att se till att processerna alltid lever?? Ditt designmönster borde ju även tillse att det inte kan skapas fler instanser än vad som anges i classen TimerMonitor.

Sedan undrar jag om trådar som är satta som daemons (demoner) fortsätter att leva efter det att applikationen stängs/startas om, eller dör de också samtidigt? Vad är isådanafall skillnaden mellan demoner och "vanliga" trådar??

Många funderingar blir det... :)

spangoMedlem sedan juni 20006 147 inlägg
#6

Trådar dör när deras föräldraprocesser (i detta fall själva programmet java) dör. Om de är satta till daemon betyder det att de inte är tillräckliga att hålla en processen levande, JVM:en stängs ner när den sista icke-daemon-tråden slutar rulla.

Kom ihåg att singletonmönstret bara funkar inom en process. Drar du igång en till process, skulle den starta andra trådar. Således måste ditt cronjobb kommunicera direkt med den process som har instanserna av trådarna, drar du igång en ny instans av JVM:en, kommer den starta nya trådar och konstatera att alla trådar rullade som de skulle. Vilket stämmer, fastän det råkar vara något för många trådar...

\t Du får hålla isär begreppen också - processer är instanser av program (sanning med en hel del modifikation ;) ), medan trådar är parallella flöden av exekvering inuti en process. Processer har separat minnesutrymme och så, medan alla trådar i en process delar på samma minne.

andreascarlssonMedlem sedan feb. 2003211 inlägg
#7

Således måste ditt cronjobb kommunicera direkt med den process som har instanserna av trådarna

Jo, men om jag sätter trådarna (av typen java.util.Timer) till static då? Då borde det ju bara finnas en enda instans av dem, eller (iaf. inom samma process/applikation)?

Brukar det förresten finnas flera instanser av samma webapplikation i gång samtidigt?? (Kör på Tomcat)

Hur sjutton skall jag göra egentligen?? Jag trodde detta skulle bli en lätt match, men jag är bara förvirrad nu... :)

spangoMedlem sedan juni 20006 147 inlägg
#8

Nej, Tomcat bör bara ha en instans igång. Det är normalt bättre att dra igång trådar inom processen i stället för att starta nya processer. Arbetar man med Java är det nästan det enda sättet att arbeta.

andreascarlssonMedlem sedan feb. 2003211 inlägg
#9

Ok! Tack för all hjälp Spango!

Jag skall försöka sätta ihop allt detta till en fungerande lösning nu... ;)

127 ms totalt · 3 externa anrop · cache AV · v20260731051352-full.56cc9887
0 ms — hämta statistik (cache)
0 ms — hämta forumlista (cache)
125 ms — hämta tråd, inlägg och bilagor (db)