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

[Java] Volgorde locken van een field.

Pagina: 1
Acties:

Verwijderd

Topicstarter
Het gaat om dit stukje code:
Java:
1
2
3
4
5
6
7
8
9
10
@Test
public void testRequestThread() {
    threadStarted=false;
    monitor.requestThread(new Runnable(){
        public void run(){
            ThreadMonitorTest.threadStarted=true;
        }
    }, "TestThread", 0);
    assertTrue(threadStarted);
}

Dit is een unittest een request van een thread voor een bepaalde runnable aan een klasse ThreadMonitor. ThreadMonitor gaat voor de runnable een thread aanmaken, en deze starten. (Ik weet het, ingewikkelde constructie, maar daar zijn redenen voor.) threadStarted is een static field van de testklasse.
Nu, om te testen of hij die thread wel mooi aanmaakt en start heb ik deze testmethode geschreven. De test slaagt gewoon. Maar, ik heb er serieuze bedenkingen bij. Je kan namelijk niet weten of hij eerst die 'assertTrue' gaat doen, of eerst threadStarted op true zet. Ik weet het, ik kan synchronizen op dat object, maar dat lost nog altijd niets op, want ik weet nog altijd niet wie eerst het lock gaat krijgen.
Een mogelijke oplossing is gewoon 0.1s wachten voor ik ga checken, maar dat is betrekkelijk vuil. En ik kan me nog wel iets bedenken met notifiers, maar het blijft een testmethode, dus ik denk/hoop dat het niet zo moeilijk hoeft. Ik heb het gevoel dat de oplossing erg gemakkelijk is, maar ja...
Wat heb ik gedaan? Vooral opgezocht in 'Java: Concurrency in practice', maar daar vind ik het niet echt.

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Tjah, de enige manier om zeker te weten dat een thread goed gestart is, is kijken, eventueel herhaaldelijk, of er binnen redelijke tijd iets gebeurt dat door die thread gedaan is.

monitor.requestThread geeft niet toevallig het betreffende Thread object terug? Want in dat geval kan je threadObject.join() gebruiken om zeker te weten dat de thread geeindigd is. Eventueel een monitor object in je testklasse opnemen en met introspectie het betreffende thread object benaderen?

[ Voor 3% gewijzigd door Confusion op 26-09-2007 17:53 ]

Wie trösten wir uns, die Mörder aller Mörder?


Verwijderd

Topicstarter
Hmmm, ik kan die methode inderdaad misschien dat thread object laten teruggeven, dat klopt eigenlijk nog wel met het concept van de methode. Goed idee, merci!

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

Alarmnummer

-= Tja =-

1) Waarom zou je de started eigenschap van een thread willen uitlezen?

2) Gebruik je nog andere modifiers op die static variable? Zo nee dan loop je kans op visibility problemen.

Ik heb trouwens voor Prometheus een unittest library opgezet om concurrent programma's te testen.

Dit is bv de TestThread die je kunt gebruiken om veel state op uit te lezen:
http://prometheus.codehau...stsupport/TestThread.html

Verwijderd

Topicstarter
Alarmnummer schreef op donderdag 27 september 2007 @ 12:19:
1) Waarom zou je de started eigenschap van een thread willen uitlezen?
Omdat die requestThread methode die thread ook moet starten. (onder bepaalde omstandigheden toch, maar die code heb ik weggelaten omdat ze niet echt ter zake doet) En ik moet dus kunnen checken of die thread echt wel gestart is. Want ja, als iemand/ikzelf die methode in de toekomst herschrijft moet mijn unittest dus zeker ook checken of die nieuwe implementatie die thread ook wel degelijk start.
2) Gebruik je nog andere modifiers op die static variable? Zo nee dan loop je kans op visibility problemen.
Ja, ik heb die gewoon public gemaakt.
Ik heb trouwens voor Prometheus een unittest library opgezet om concurrent programma's te testen.

Dit is bv de TestThread die je kunt gebruiken om veel state op uit te lezen:
http://prometheus.codehau...stsupport/TestThread.html
Ga ik zeker eens naar kijken. Dank je!

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

Alarmnummer

-= Tja =-

Verwijderd schreef op donderdag 27 september 2007 @ 12:38:
[...]

Omdat die requestThread methode die thread ook moet starten. (onder bepaalde omstandigheden toch, maar die code heb ik weggelaten omdat ze niet echt ter zake doet) En ik moet dus kunnen checken of die thread echt wel gestart is.
Hmm tja.. Werken met globals geeft mij een redelijk onderbuik gevoel.

Ik kan het zelf controleren door t.assertIsStarted() te doen.
Ja, ik heb die gewoon public gemaakt.
En niet volatile :) Dat betekend dat de waarde die de thread schrijft, helemaal niet zichtbaar hoeft te zijn binnen andere threads. Dus volatile maken dat ding.

[ Voor 13% gewijzigd door Alarmnummer op 27-09-2007 13:15 ]


  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

Alarmnummer schreef op donderdag 27 september 2007 @ 13:09:
En niet volatile :) Dat betekend dat de waarde die de thread schrijft, helemaal niet zichtbaar hoeft te zijn binnen andere threads. Dus volatile maken dat ding.
Hoewel hij in dit geval gered wordt door de Thread.join().

Wie trösten wir uns, die Mörder aller Mörder?


Verwijderd

Topicstarter
En niet volatile :) Dat betekend dat de waarde die de thread schrijft, helemaal niet zichtbaar hoeft te zijn binnen andere threads. Dus volatile maken dat ding.
Ik had er in eerste instantie op gelocked hoor :). Ik had dat alleen al weg gehaald omdat ik besefte dat je dan nog niet weet wie eerst de lock krijgt.

En over die global: Gohja, het is een losstaande testklasse, dus niet zo een ramp dacht ik... Hoe zou je het anders/beter doen? Zonder er echt veel werk in te steken, want ja, het werkt nu perfect...

  • Vaudtje
  • Registratie: April 2002
  • Niet online
Als je een bepaalde implementatie (aanroepen van run() ) wil afdwingen bij het JUnitTesten van een interface (de monitor), kun je dat met een Mock framework (JMock, EasyMock) door een Runnable mock te maken en controleren of de run() methode wel is aangeroepen.
De API doe ik ff uit de losse hand, maar hopelijk komt het idee over.
Java:
1
2
3
Thread monitoredThread = (Thread) EasyMock.createObject(Runnable.class).expects().method("run");
monitor.requestThread(monitoredThread, "TestThread",0);
EasyMock.verify(monitoredThread);

Voor begripsvorming rond Mocks: http://martinfowler.com/articles/mocksArentStubs.html
edit:
ik zie nu dat dit in dit geval helemaal niets gaat helpen bij het oplossen van je probleem...join(10) op een te retourneren Thread zoals vermeld lijkt me verstandiger

[ Voor 14% gewijzigd door Vaudtje op 27-09-2007 18:30 ]

In deeze zin staan drie fauten


Verwijderd

Topicstarter
Hmmm, ziet er ook best wel interessant uit! Probleem met zo'n dingen is wel dat het een thesis is die we doen bij een grote financiele instelling. Gevolg: het is zo closed source als het maar kan zijn, en alle libs die we eventueel zouden gebruiken, daar moeten we fatsoenlijke supportcontracten voor kunnen krijgen. Anyway, ik leer veel bij hier, ideaal dus :)

  • den 150
  • Registratie: Oktober 2002
  • Niet online
Confusion schreef op donderdag 27 september 2007 @ 16:47:
[...]

Hoewel hij in dit geval gered wordt door de Thread.join().
Nope, aangezien de waarde is geschreven door een andere thread is er zonder locking of volatile geen enkele garantie dat die nieuwe waarde ooit zichtbaar is voor andere threads. Of die thread beëindigd is of niet heeft daar geen invloed op.

Ontopic: ik zou in dit geval ook grijpen naar EasyMock. Supportcontracten voor alle libs is onzin, je gaat me niet vertellen dat jij support hebt op junit :). Kan je dit niet aan management verkopen aangezien het enkel wordt gebruikt om te testen, en dus nooit in productie code zal geraken?

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

den 150 schreef op donderdag 27 september 2007 @ 20:07:
Nope, aangezien de waarde is geschreven door een andere thread is er zonder locking of volatile geen enkele garantie dat die nieuwe waarde ooit zichtbaar is voor andere threads. Of die thread beëindigd is of niet heeft daar geen invloed op.
Ik zei ook niet dat het kwam doordat de thread geeindigd was. Ik zei dat het kwam door het gebruik van thread.join(), waardoor de aanroepende thread zeker weet dat de thread geeindigd (en dat alle acties van die thread zichtbaar zijn).
* When a thread terminates and causes a Thread.join in another thread to return, then all the statements executed by the terminated thread have a happens-before relationship with all the statements following the successful join. The effects of the code in the thread are now visible to the thread that performed the join.
bron

[ Voor 12% gewijzigd door Confusion op 28-09-2007 07:33 ]

Wie trösten wir uns, die Mörder aller Mörder?


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

Alarmnummer

-= Tja =-

Confusion schreef op donderdag 27 september 2007 @ 16:47:
[...]

Hoewel hij in dit geval gered wordt door de Thread.join().
In zijn voorbeeld zie ik geen Thread.join voorkomen. Maar ik begrijp het punt dat je wilt maken.

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

Alarmnummer

-= Tja =-

Verwijderd schreef op donderdag 27 september 2007 @ 17:31:
[...]
En over die global: Gohja, het is een losstaande testklasse, dus niet zo een ramp dacht ik... Hoe zou je het anders/beter doen?
Daar heb ik die hele testsupport library voor geschreven bij Prometheus.

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

Alarmnummer

-= Tja =-

den 150 schreef op donderdag 27 september 2007 @ 20:07:
[...]
Nope, aangezien de waarde is geschreven door een andere thread is er zonder locking of volatile geen enkele garantie dat die nieuwe waarde ooit zichtbaar is voor andere threads. Of die thread beëindigd is of niet heeft daar geen invloed op.
Er zijn dus meer waaronder Thread.join en Thread.start. Voor het hele overzicht kun je ff kijken naar Java Concurrency in Practice.

[ Voor 8% gewijzigd door Alarmnummer op 27-09-2007 22:56 ]


  • misfire
  • Registratie: Maart 2001
  • Laatst online: 12-10-2024
Je zou ook eens kunnen kijken naar een nieuw project van de Bill "Findbugs" Pugh studenten: MultithreadedTC. Dat is bedoeld om fine-grained concurrency tests uit te kunnen voeren, zoals jij nu ook wilt. Het werkt op basis van een "metronome" systeem, wat ik zelf een erg verfrissende en simpele oplossing vind voor dit soort problemen. Zie de link voor uitleg en voorbeelden.
Pagina: 1