Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[EJB3/JBoss] vraag mbt concurreny(?)

Pagina: 1
Acties:

  • Y0ur1
  • Registratie: Oktober 2000
  • Niet online
Ik heb (denk ik) een probleempje met concurreny, en mogelijk met de hele opzet van deze schoolopdracht.

Ik heb een remote stateless session bean die in de meest basale vorm 1 HashMap en 2 methodes add en delete, voor resp. het toevoegen en verwijderen van boeken.

Nu zou je zeggen dat hij 100 boeken toevoegt en dan verwijderd, maar vaak blijven er boeken in de HashMap bestaan nadat de client klaar is, ze blijven dus 'over'.

Wie kan dit verklaren? Het heeft er misschien mee te maken dat voor iedere methode aanroep er een nieuwe EJB uit de pool wordt gehaal, maar het fijne weet ik er niet vanaf, iemand die dit kan uitleggen?

Ik gebruik JBoss 4.4.2GA icm EJB3 met annotations.


Dan de client:
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
29
30
31
32
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class Client {
    public static void main(String[] args) {
        
        InitialContext ic = null;               
        try {
            ic = new InitialContext();

            ic.addToEnvironment("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
            ic.addToEnvironment("java.naming.provider.url", "jnp://127.0.0.1:1099");        
        } catch (NamingException e) {
            System.out.println("Exceptie opgetreden: " + e.getMessage());
        }
        
        LibraryManagerSession lms = null;

        try {
            lms = (LibraryManagerSession) ic.lookup("LibraryManagerSessionBean");

            for(int i=0; i<100; i++) {
                lms.newBook("book" + i);
                lms.removeBook("book" + i);
            }
        } catch (NamingException e) {
            System.out.println("Exceptie opgetreden: " + e.getMessage());
        }

        lms.clear();
    }
}


EJB:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
import java.util.HashMap;
import java.util.HashSet;

import javax.ejb.Remote;
import javax.ejb.Stateless;

@Stateless
@Remote(LibraryManagerSession.class)

public class LibraryManagerSessionBean implements LibraryManagerSession{
    private HashMap<String, String> books = new HashMap<String, String>();
    
    public void newBook(String name) {
        System.out.println("LibraryManagerSessionBean.newBook(): aangeroepen");
        
        if(!books.containsKey(name)) {
            books.put(name, null);
            System.out.println("LibraryManagerSessionBean.newBook(): nieuw book("+name+") toegevoegd (" +books+ ")");
        }
    }
    
    public void removeBook(String title) {
        System.out.println("LibraryManagerSessionBean.removeBook(): aangeroepen");
        
        if(books.containsKey(title)) {
            books.remove(title);
            System.out.println("LibraryManagerSessionBean.removeBook(): book verwijderd("+title+") (" +books+ ")");
        }
    }
    
    public void clear() {
        books.clear();
        System.out.println("aantal books over:" + books.size());
        System.out.println("LibraryManagerSessionBean.clear(): books HashMap is geleegd");
    }

    public LibraryManagerSessionBean() {
        
    }

}

  • BCC
  • Registratie: Juli 2000
  • Laatst online: 22:06

BCC

Staan ze niet alleen maar in de JBOS cache en zijn ze gewoon nog niet weggeschreven naar de database?

Na betaling van een licentievergoeding van €1.000 verkrijgen bedrijven het recht om deze post te gebruiken voor het trainen van artificiële intelligentiesystemen.


  • Y0ur1
  • Registratie: Oktober 2000
  • Niet online
BCC schreef op maandag 11 februari 2008 @ 19:00:
Staan ze niet alleen maar in de JBOS cache en zijn ze gewoon nog niet weggeschreven naar de database?
De database is in deze opdracht even de HashMap, geen database dus, het is nog niet persistent.

  • BCC
  • Registratie: Juli 2000
  • Laatst online: 22:06

BCC

Y0ur1 schreef op maandag 11 februari 2008 @ 19:01:
[...]

De database is in deze opdracht even de HashMap, geen database dus, het is nog niet persistent.
Sorry, ik was te lui om je code te lezen, dat zal ik nou even doen :)Wat zeggen je printlines?

[ Voor 4% gewijzigd door BCC op 11-02-2008 19:04 ]

Na betaling van een licentievergoeding van €1.000 verkrijgen bedrijven het recht om deze post te gebruiken voor het trainen van artificiële intelligentiesystemen.


  • momania
  • Registratie: Mei 2000
  • Laatst online: 00:01

momania

iPhone 30! Bam!

Je zou de HashMap static final moeten maken, en eigenlijk ook nog synchronized.
Java:
1
private static final HashMap<String, String> books = Collections.synchronizedMap(new HashMap<String, String>()); 


NB
Maar dan nog krijg je een probleem als je gaat clusteren aangezien dit maar 1 HashMap per JVM garandeerd ;)

offtopic:
Topic past volgens mij beter in Programming trouwens :)

[ Voor 10% gewijzigd door momania op 11-02-2008 19:17 ]

Neem je whisky mee, is het te weinig... *zucht*


  • Y0ur1
  • Registratie: Oktober 2000
  • Niet online
momania schreef op maandag 11 februari 2008 @ 19:14:
Je zou de HashMap static final moeten maken, en eigenlijk ook nog synchronized.
Java:
1
private static final HashMap<String, String> books = Collections.synchronizedMap(new HashMap<String, String>()); 


NB
Maar dan nog krijg je een probleem als je gaat clusteren aangezien dit maar 1 HashMap per JVM garandeerd ;)
static mag toch niet ivm clustering? het wordt niet aangeraden iig, en synchronized heeft toch geen zin? Er kunnen toch niet meerdere threads op een ejb werken.

  • momania
  • Registratie: Mei 2000
  • Laatst online: 00:01

momania

iPhone 30! Bam!

Y0ur1 schreef op maandag 11 februari 2008 @ 19:17:
[...]

static mag toch niet ivm clustering?
Dat zeg ik toch ook? ;)

Neem je whisky mee, is het te weinig... *zucht*


  • Y0ur1
  • Registratie: Oktober 2000
  • Niet online
Ja oke, maar het gaat helemaal de mist in bij mijn test. De printlines geven aan dat er vaak removes worden gedaan maar dan kan hij het item niet vinden in de HashMap. En volgens mij komt dat omdat wanneer een functie loopt in een session bean en er komt nog een methode aanroep binnen dan wordt deze geleid naar een nieuwe session bean. Vandaar dat ik dus de onderstaande meldingen krijg. Ik heb soms te maken met een andere instantie van een session bean (kijk maar naar de toString van books.

code:
1
2
3
4
5
6
7
8
9
10
11
12
19:12:11,001 INFO  [STDOUT] LibraryManagerSessionBean.newBook(): nieuw book(book6) toegevoegd ({book4=null, book0=null, book6=null, book3=null, book2=null, book5=null, book1=null})
19:12:11,008 INFO  [STDOUT] LibraryManagerSessionBean.removeBook(): aangeroepen
19:12:11,011 INFO  [STDOUT] LibraryManagerSessionBean.removeBook(): book verwijderd(book6) ({book9=null, book8=null, book7=null})
19:12:11,019 INFO  [STDOUT] LibraryManagerSessionBean.newBook(): aangeroepen
19:12:11,022 INFO  [STDOUT] LibraryManagerSessionBean.newBook(): nieuw book(book7) toegevoegd ({book4=null, book0=null, book6=null, book3=null, book2=null, book5=null, book7=null, book1=null})
19:12:11,031 INFO  [STDOUT] LibraryManagerSessionBean.removeBook(): aangeroepen
19:12:11,033 INFO  [STDOUT] LibraryManagerSessionBean.removeBook(): book verwijderd(book7) ({book9=null, book8=null})
19:12:11,041 INFO  [STDOUT] LibraryManagerSessionBean.newBook(): aangeroepen
19:12:11,044 INFO  [STDOUT] LibraryManagerSessionBean.newBook(): nieuw book(book8) toegevoegd ({book4=null, book0=null, book6=null, book8=null, book3=null, book2=null, book5=null, book7=null, book1=nu
ll})
19:12:11,058 INFO  [STDOUT] LibraryManagerSessionBean.removeBook(): aangeroepen
19:12:11,061 INFO  [STDOUT] LibraryManagerSessionBean.removeBook(): book verwijderd(book8) ({book9=null})

  • Y0ur1
  • Registratie: Oktober 2000
  • Niet online
momania schreef op maandag 11 februari 2008 @ 19:14:
Je zou de HashMap static final moeten maken, en eigenlijk ook nog synchronized.
Java:
1
private static final HashMap<String, String> books = Collections.synchronizedMap(new HashMap<String, String>()); 


NB
Maar dan nog krijg je een probleem als je gaat clusteren aangezien dit maar 1 HashMap per JVM garandeerd ;)

offtopic:
Topic past volgens mij beter in Programming trouwens :)
Maar waarom final? dan kan ik er toch niks meer aan toevoegen. En waarom synchronized, een EJB instantie is niet multi-threaded.

  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 19:37

Nick_S

++?????++ Out of Cheese Error

Je zegt zelf, dat er meerdere beans gemaakt kunnen worden, dus de Map per instantie gaat niet werken.

Ik zie ook Stateless staan, terwijl je dus wel state hebt tussen twee aanroepen (namelijk je Map)

Verder zegt final iets over je referentie (in dit geval books) en niet over je object (new HashMap()) Bij final mag je de referentie niet meer wijzigen, maar nog wel methodes aanroepen op het object waar de referentie naar toe wijst.

Als je dus een stateless bean wil hebben, moet je zorgen dat er geen data word opgeslagen in interne verzamelingen, maar altijd een andere partij (bjivoorbeeld een database laag) daarvoor aanspreekt. Voor de test zou een static synchronized map ook een "externe" partij kunnen zijn, die kan door elke thread veilig aangesproken worden en elke thread beschikt ook over dezelfde datasource, net zoals bij een database, dus.

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


  • momania
  • Registratie: Mei 2000
  • Laatst online: 00:01

momania

iPhone 30! Bam!

Nick_S schreef op dinsdag 12 februari 2008 @ 09:42:
Voor de test zou een static synchronized map ook een "externe" partij kunnen zijn, die kan door elke thread veilig aangesproken worden en elke thread beschikt ook over dezelfde datasource, net zoals bij een database, dus.
Wat dus ook weer alleen maar op 1 JVM werkt. Dus let daar op dat het in een cluster weer mis gaat.
Waar het ook nog mis kan gaan is op een multi-core cpu. Gebruik daarvoor volatile zodat je altijd werkt met het object in je main memory. :)

offtopic:
Dit is een schoolopdracht trouwens zei je? Dan is dit wel 1 van de eerste serieuze schoolopdrachten die ik ben tegen gekomen hier op GoT qua java. :)

[ Voor 12% gewijzigd door momania op 12-02-2008 10:16 ]

Neem je whisky mee, is het te weinig... *zucht*


  • Nick_S
  • Registratie: Juni 2003
  • Laatst online: 19:37

Nick_S

++?????++ Out of Cheese Error

momania schreef op dinsdag 12 februari 2008 @ 10:14:
[...]

Wat dus ook weer alleen maar op 1 JVM werkt. Dus let daar op dat het in een cluster weer mis gaat.
Waar het ook nog mis kan gaan is op een multi-core cpu. Gebruik daarvoor volatile zodat je altijd werkt met het object in je main memory. :)

offtopic:
Dit is een schoolopdracht trouwens zei je? Dan is dit wel 1 van de eerste serieuze schoolopdrachten die ik ben tegen gekomen hier op GoT qua java. :)
Als je inderdaad gaat clusteren met meerdere multicore processoren ben je met een hele serieuze schoolopdracht bezig. :) Voor multicore is inderdaad volatile de oplossing, voor clusteren een "serieuze" backend.

'Nae King! Nae quin! Nae Laird! Nae master! We willna' be fooled agin!'


  • Macros
  • Registratie: Februari 2000
  • Laatst online: 22:07

Macros

I'm watching...

Volatile is toch niet nodig? Je hebt toch maar 1 instantie van je Map die niet meer veranderd.
Je kan hem dus het beste private static final maken. Ook zou ik niet SynchronizedMap gebruiken, maar ConcurrentHashMap, die is in alle gevallen (vele malen) sneller dan Collections.synchronizedMap(new HashMap()).

"Beauty is the ultimate defence against complexity." David Gelernter


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

Alarmnummer

-= Tja =-

*laat even de EJB discussie voor wat het is*

Volatile is bij static velden die direct worden geinstantieerd niet nodig. Er is een gegarandeerde happens before relatie tussen de write van het veld, en iedere toekomstige read.

Persoonlijk zou ik het veld final maken omdat je het niet meer kunt wijzigen. Maar vanuit het JMM gezien is private static Map blamap = ..... voldoende.
Pagina: 1