[Java] Oplossing voor scheduled en parallel lopende Threads

Pagina: 1
Acties:
  • 150 views sinds 30-01-2008
  • Reageer

  • Grub
  • Registratie: Juni 1999
  • Laatst online: 11-02-2024
Ik ben op zoek naar een goede oplossing om processen gescheduled en eventueel parallel te laten lopen. Probleem is alleen dat mn requirements net iets hoger liggen dan bij simpel thread programming, vandaar dat ik na 2 uur zoeken nog geen steek opgeschoten ben, terwijl ik ervan overtuigd ben dat er wel iets te vinden moet zijn waar dit mee te bouwen is.

Ruwweg heb ik de volgende requirements:
1. Een process bestaat uit 3 delen:
* init() - hier open ik bijv. een socket
* runTask() - hier voer ik een een task een aantal maal uit
* terminate() - hier close ik bijv. het socket weer

2. De task in runTask moet meerdere malen kunnen worden uitgevoerd tussen init en terminate. Dit moet op twee manieren kunnen:
(a) met een pauze ertussen,
(b) fixed delay. Hiermee bedoel ik dus dat als een task 10 seconden duurt, en het delay is 2s, dan heb je na 7 seconden 3 tasks parralel runnen.

3. Het zou heel erg mooi zijn als het process bruut afgebroken zou kunnen worden. Hiermee bedoel ik dus dat ook de task als die op dat moment bezig is, direct moet stoppen. Volgens mij kan dit niet zomaar en hangt het af van de implementatie in de task, dit zou dan regelmatig een boolean aborted moeten checken. Maarja, das lastig als de methode blocked luistert op een socket.

Mijn vraag is: is er ergens een oplossing waarmee dit te realiseren is? Ik heb gegeken naar java.util.concurrent, en het Quartz project, maar voor zover ik kan zien gaat het me niet lukken requirement (1) te realiseren met deze oplossingen.

  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 25-09-2023
Punt 1 en 2 zouden niet zo ingewikkeld moeten zijn. Punt 3 is het probleemgeval. Als mijn glazen bol het goed heeft, dan zijn non-blocking sockets een oplossing voor je. Kijk bijvoorbeld even naar deze slides gemaakt door een oud-klasgenoot: http://www.cs.uu.nl/docs/vakken/no/reactor.pdf.

[ Voor 19% gewijzigd door Infinitive op 20-09-2006 17:38 ]

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Grub schreef op woensdag 20 september 2006 @ 17:22:
Ruwweg heb ik de volgende requirements:
1. Een process bestaat uit 3 delen:
* init() - hier open ik bijv. een socket
* runTask() - hier voer ik een een task een aantal maal uit
* terminate() - hier close ik bijv. het socket weer
Je zou gebruik kunnen maken van de java.util.concurrent.Executor om jobs in te laten executen. En je kunt verschillende ontwerpen gebruiken. Je zou bv voor ieder stap die uitgevoerd met worden een runnable maken die die taak uitvoert en aan het einde van die taak kijkt die welke runnable daarna aangemaakt moet worden (van InitRunnable naar RunTaskRunnable bv, of van RunTaskRunnable die dan een TerminateRunnable aanmaakt).

Maar je zou ook een enkele runnable kunnen maken die zoiets doet:

code:
1
2
3
4
5
6
7
8
9
10
public void run(){
    init();
    try{
       while(nextJob()){
             execute();
       }
    }finally{
         terminate();
    }
}


Maar ik weet niet genoeg van je requirements om hier echt iets zinnigs mee te kunnen.
2. De task in runTask moet meerdere malen kunnen worden uitgevoerd tussen init en terminate. Dit moet op twee manieren kunnen:
(a) met een pauze ertussen,
(b) fixed delay. Hiermee bedoel ik dus dat als een task 10 seconden duurt, en het delay is 2s, dan heb je na 7 seconden 3 tasks parralel runnen.
de java.util.concurrency.ScheduledExecutor heeft dit soort functionaliteit. Dus misschien is het opdelen van taken in kleinere runnable's wel zo handig. Dan kan bv de RunTask na het einde kijken wat er gedaan moet worden: terminaten? nieuwe met een bepaalde pauze? of direct?
3. Het zou heel erg mooi zijn als het process bruut afgebroken zou kunnen worden. Hiermee bedoel ik dus dat ook de task als die op dat moment bezig is, direct moet stoppen. Volgens mij kan dit niet zomaar en hangt het af van de implementatie in de task, dit zou dan regelmatig een boolean aborted moeten checken. Maarja, das lastig als de methode blocked luistert op een socket.
Als je een thread gaat interrupten terwijl die geblocked is omdat hij een read op een socket aan het doen is terwijl er geen input is, krijg je een mooie InterruptedIOException. Dus een read (en write) is dus gevoelig voor interrupts.

Hoe lang verwacht je dat de 'RunTask' gaat duren? Als dat een hele korte tijd is, dan zou je er voor kunnen kiezen om binnen die runtask niet te controleren en alleen gaat controleren als een bepaalde stap n je systeem afgerond is. Als je wel een lang lopende taak hebt, tja.. dan zul je wel regelmatig moeten controleren. Je zou er ook voor kunnen kiezen om de interrupt status vlag uit te lezen.

  • TukkerTweaker
  • Registratie: November 2001
  • Laatst online: 13-02 14:51
Misschien is Quartz iets voor jou.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Je kunt het ThreadPool mechanisme (valt te vergelijken met de Executor) en het Timer mechanisme gebruiken. Maar daarmee zijn de problemen nog niet opgelost. Ik kan nog wel een aantal oplossingen bedenken: java.util.Timer en WorkManager.

De gebruiker heeft volgens mij meer aan hoe een 'executor' en 'timer' gebruikt kan worden in zijn ontwerp. Concrete implementaties zullen denk ik niet zo veel daar aan veranderen.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Infinitive schreef op woensdag 20 september 2006 @ 17:35:
Punt 1 en 2 zouden niet zo ingewikkeld moeten zijn. Punt 3 is het probleemgeval. Als mijn glazen bol het goed heeft, dan zijn non-blocking sockets een oplossing voor je. Kijk bijvoorbeld even naar deze slides gemaakt door een oud-klasgenoot: http://www.cs.uu.nl/docs/vakken/no/reactor.pdf.
Blocking io is gevoelig voor interrupts. Dus als jij een Thread wilt interrupten die ligt te waiten, zou dat geen enkel probleem hoeven te zijn.

Het reactor design pattern zet je om een hele andere reden in: je zoekt een structuur waarmee je eenvoudig non blocking io via een of meer threads kunt laten verwerken door een aantal handlers.

  • Grub
  • Registratie: Juni 1999
  • Laatst online: 11-02-2024
Oke ik was wat te snel met mn conclusie dat het niet ging lukken met java.util.concurrent... :z

Dit is mn oplossing:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
        final ExecutorService executor = Executors.newCachedThreadPool();
        int maxCount = 10;
        long rate = 1000L;
        Runnable runTask = new RunTask();

        new InitTask().run();

        int count = 1;
        long start = System.currentTimeMillis() - rate; //first time, don't wait but start immediately
        try {
            while (count <= maxCount) {
                while (System.currentTimeMillis() < start + count * rate) {
                    //wait for correct starttime
                }
                executor.execute(runTask);
                count++;
            }
        } catch (RejectedExecutionException e) {
            System.out.println("process aborted");
            //this exception is thrown when executor is terminated with shutdownNow()
            //in the task, check for Thread.interrupted() to abort immediately
        }

        executor.shutdown(); 
        while (!executor.isTerminated()) {
            //wait till all tasks have finished
        }
        new TerminateTask().run();

Bedankt voor de reacties. Een thread aborten gaat idd niet zo makkelijk, je moet er in de thread rekening mee houden. Ik heb uiteindelijk niet voor Quartz gekozen omdat ik me liever met een standaard api werk.

[ Voor 7% gewijzigd door Grub op 21-09-2006 12:25 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Tip:
Denk eens na of jou systeem ook graceful degrade (wat zouden de gevolgen kunnen zijn als er veel requests binnen komen).

[ Voor 44% gewijzigd door Alarmnummer op 21-09-2006 13:26 ]

Pagina: 1