Avatar billede kasseper Nybegynder
02. juli 2003 - 09:53 Der er 11 kommentarer og
1 løsning

ThreadPool Doug Lea - links

Hej hej

Doug Lea har udviklet en pakke der bliver en del af java 1.5, men den kan hentes på nettet, se evt link :
http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html

Det jeg søger er links eller eksempler på brugen af PooledExecutor da jeg ikke helt kan forstå den.
Avatar billede arne_v Ekspert
02. juli 2003 - 11:17 #1
Efter at have læst dokumentationen ser det rimeligt simpelt ud.

Hvis du vil have en pool af 5 threads laver du:

PooledExecutor pool = new PooledExecutor(5);

og så kalder du pool.execute med objekter som er Runnable - hvis
der er en ledig tråd så kører den med det samme - hvis der ikke er en
ledig tråd så venter den indtil der bliver en ledig.

Det er altså en nem måde logisk at køre et stort antal tråde på
men således at der fysisk kun er et begrænset antal tråde.
Avatar billede kasseper Nybegynder
02. juli 2003 - 11:54 #2
Hermed en mere detaljeret oversigt over mine problemmer :

Jeg har lavet en Pool - uden parameter, da jeg pludselig kan få rigtig mange requests...:

PooledExecutor pool = new PoolExecuter();

sat keepAliveTime :
pool.setKeepAliveTime(10000);

sat poolMinimumsize :
pool.setMinimumPoolSize(5);

og started 5 default tråde :
pool.createThreads(5);

Spørgsmål 1 :
Når nu jeg kalder createThreads(5), hvilke 5 tråde er det så den starter op ?
Jeg giver jo ikke noget runnable object her ?
Er det så bare PooledExecuter's interne worker tråde, som så bare står klar til at tage imod mine pool.execute kald ??????

Lad os sige at jeg laver et runable object der extender Thread, og lader det sleepe i 5 sekunder i run metoden.

Jeg kalder nu pool.execute med mit runnable object 50 gange, laver den så 50 interne worker tråde til at varetage mine kald, da der jo går 5 sekunder inden de fem default tråde bliver færdige...?

Og hvordan fungerer det rent logisk.
Udfører de interne worker tråde, mine runnable objecter's run metode, til de er færdige, og herefter garbage collector mine runnableobjecter ????
Hvis mine runnable objecter nu har nogle public metoder, hvordan kalder jeg så dem, efter jeg har kaldt pool.execute ???Kan jeg overhoved det?????

Shit en masse spørgsmål, håber du har tid og lyst til at svar.
Smider lidt flere point i nakken, så du for lidt mere ud af det....

På forhåbentlig genhør !
Avatar billede kasseper Nybegynder
02. juli 2003 - 12:30 #3
Jeg tror at jeg fik besvaret de fleste af mine egne spørgsmål, på nær det sidste....
Hvordan kommunikere jeg med en tråd der er sat igang med pool.execute....?
Avatar billede arne_v Ekspert
02. juli 2003 - 12:32 #4
Nu har jeg jo ikke checket hans kilde kode, så det bliver kun lad os
kalde det kvalificerede formodninger.

createThreads(5) laver 5 Java tråde som bare står og venter på
opgaver.

Når du kalder pool.execute med en Runnable 50 gange så smider du 50
opgaver i kø.

De 5 tråde går så igang med at hente opgaver og udføre dem. D.v.s. at
der er maksimalt 5 samtidige opgaver igang.

Når der er ikke er flere opgaver så ligger tråedene sig til at sove igen.

Ja de må køre din run metode.

Og dine objekter bliver selvfølgelig først GC'et når der ikke er
flere referancer til dem. Og det vil der vel typisk være i den
kode der kalder pool.execute.

Og ja du kan da sagtens kalde metoder på de objekter.

Du gemmer bar en referance til dem og kalder metoderne.

Eksempel:

MySpecialRunner r = new MySpecialRunner();
pool.execute(r);
while(r.percentDone() < 100) {
    System.out.println(r.percentDone() + " percent done");
}
Avatar billede arne_v Ekspert
02. juli 2003 - 12:35 #5
Du skal selvfølgelig være lidt forsigtig med at kalde noget der bliver
kørt i en tråd fordi du ikke helt ved hvor langt det er kommet
(fuldstændigt det samme om du bruger pool eller selv starter tråde).
Avatar billede kasseper Nybegynder
02. juli 2003 - 12:39 #6
Endnu et spørgsmål :
Her er en del af min kode, som kan køre umiddelbart, hvis man altså importer Doug Lea's kode selvfølgelig
---------------------------------------------------------------------------public class PoolManager {
   
    static PooledExecutor pool;
   
    /** Creates a new instance of PoolManager */
    public PoolManager(){
       
        pool = new PooledExecutor(3);
        pool.setKeepAliveTime(1000);
        pool.setMinimumPoolSize(2);
        pool.createThreads(3);
        try{
            pool.execute(new SleeperThread("test1", 1000));
            pool.execute(new SleeperThread("test2", 800));
            pool.execute(new SleeperThread("test3", 600));
            pool.execute(new SleeperThread("test4", 400));
        }
        catch(Exception e) {
            System.out.println(e.toString());
        }
    }
   
    private class SleeperThread extends Thread {
        private String name = "";
        private int sleepnumber = 0;
        private long sleeptime = 1000;
        private boolean aLive = true;
        /** Creates a new instance of TestThread */
        public SleeperThread(String name, long sleeptime) {
            this.name = name;
            this.sleeptime = sleeptime;
        }
       
        public void run() {
            while(aLive) {
                Thread thisThread = Thread.currentThread();
                try{
                   
                    if (sleepnumber > 5)
                        kill();
                    else
                        System.out.println("Thread " + name + " slept for " + (sleeptime * sleepnumber) + " miliseks.");
                   
                    thisThread.sleep(sleeptime);
                    sleepnumber++;
                }
                catch(java.lang.InterruptedException ie) {System.out.println("thread : " + this.name + " was iterrupted !");}
               
            }
        }
       
        public void kill() {
            this.aLive = false;
        }
       
       
       
    }
   
   
    public static void main(String[] args) {
        System.out.println("START");
        PoolManager pm = new PoolManager();
        System.out.println("END");
    }
   
}
--------------------------------------------------------------------------


Hvis man sætter maks tråde til 3 og executer 4, så kører den tråde i en spøjs rækkefølge, her er output :
*********************************************************************
START
Thread test1 slept for 0
Thread test1 slept for 1000
Thread test1 slept for 2000
Thread test1 slept for 3000
Thread test1 slept for 4000
Thread test1 slept for 5000
Thread test2 slept for 0
END
Thread test3 slept for 0
Thread test4 slept for 0
Thread test4 slept for 400
Thread test3 slept for 600
Thread test2 slept for 800
Thread test4 slept for 800
Thread test3 slept for 1200
Thread test4 slept for 1200
Thread test2 slept for 1600
Thread test4 slept for 1600
Thread test3 slept for 1800
Thread test4 slept for 2000
Thread test2 slept for 2400
Thread test3 slept for 2400
Thread test3 slept for 3000
Thread test2 slept for 3200
Thread test2 slept for 4000
*********************************************************************

Altså den kører tråd 1 færdig først, hvorefter den så starter de efterfølgende 3 tråde....
Burde den ikke starte test1,2 og 3, og når så en af dem er færdig, så starter den test4 ???????????????????????????????????????????????????

Håber at du også syntes det her er lidt spændende, ellers er du no løbet skrigende bort....:)
Avatar billede arne_v Ekspert
02. juli 2003 - 13:37 #7
Jeg nærlæste lige dokumentationen:

Blocked execution policy
If the maximum pool size or queue size is bounded, then it is possible for incoming execute requests to block. There are four supported policies for handling this problem, and mechanics (based on the Strategy Object pattern) to allow others in subclasses:

Run (the default)
The thread making the execute request runs the task itself. This policy helps guard against lockup.
Wait
Wait until a thread becomes available.
Abort
Throw a RuntimeException
Discard
Throw away the current request and return.
DiscardOldest
Throw away the oldest request and return.

Tilsyneladende var min hypotese om at den blev smidt i kø ikke rigtig.

Default kører den uden tråd når alle tråde er i brug.

D.v.s. at 1, 2 og 3 starter en tråd og 4 kører run metode i main thread.

Og det forklarer hvorfor 4 hopper foran.
Avatar billede kasseper Nybegynder
02. juli 2003 - 13:39 #8
dvs. at jeg skal sætte den til wait ?????
Avatar billede arne_v Ekspert
02. juli 2003 - 13:51 #9
Ja.

Jeg synes bare ikke at det er helt klar om den så går i kø
eller den bare blocker main thread indtil der er en ledig tråd.

Men prøv og kald waitWhenBlocked.
Avatar billede kasseper Nybegynder
02. juli 2003 - 14:07 #10
nu er det nok mig der er gået kold, men hvordan hede hule helvede gør jeg det ????

Man kan på pool, kalde setBlockedExecutionHandler. Men den tager et object der hedder : PooledExecuter.WaitWhenBlocked(), men dens construktor er protected ???

daaaaaaamn, jeg er snart blind af at se på det her ...!
Avatar billede arne_v Ekspert
02. juli 2003 - 14:11 #11
Ifølge dokumentationen så kan du bare:

pool.waitWhenBlocked();

den anden må være til hvis du vil kode din helt egen policy !
Avatar billede kasseper Nybegynder
02. juli 2003 - 14:12 #12
ja der kan du se hvor blind jeg er blevet.
Mange tak for hjælpen, det kører nu, så skal den bare tunes efter mine behov..
MANGE MANGE tak.. !
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester