aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Data class multithreaded load test  (UB1.1.2) Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Data class multithreaded load test  (UB1.1.2)" Watch "Data class multithreaded load test  (UB1.1.2)" New topic
Author

Data class multithreaded load test (UB1.1.2)

Alecsandru Cocarla
Ranch Hand

Joined: Feb 29, 2008
Posts: 158
I'll share with you a multithreaded load test which I just finished writing.
It is designed to run random create/read/update/delete/finds on a UrlyBird database and Sysouts everything. It also performs at the end a small test that the database is still valid.

It uses plain JUnit, but you can probably transform it pretty easy in a main() class if you want. (JUnit is used for setUp and running, not really performing any asserts with it).

Every lock/do-something/unlock sequence is performed by three separate threads, so if you're using a 3-tier architecture (which does this sequences in a single thread) but don't know if the Data can manage separate calls from 3 threads - you can use this test.

I for one decided to use a 3-tier architecture. However, I wanted my Data class to be ready to work in a 2-tier "mode" because I suspect that the automated tests used for grading our projects want it this way.

Of course, if you're using a 2-tier, than passing this kind of test is a must.

A big advantage over the already existing tests around here is that it has Javadoc .

Here they are (it's made of two classes):






If you use these test, please come back here with opinions about it and improvements. Thanks.


SCJP 1.4 100%
SCJD 99.5%
Don Solomon
Ranch Hand

Joined: Jul 20, 2008
Posts: 48
Hey Alecsandru,
Program looks interesting. If I may offer some input. The programs appears to be overloaded with many condition statements determining Mode. You may what to study a good Design Patterns book and focus your attention on the State Pattern. You will discover that so many of your condition statements and case logic can be implemented more effectively (removed) and much of the redundant code eliminated. The "run" methods need to be placed in Runnables. This should make your code more readable and maintainable.


Software development is an exercise in thinking not coding.
Alecsandru Cocarla
Ranch Hand

Joined: Feb 29, 2008
Posts: 158
Well, you're right. I could use a State pattern and I think I 'll do it . Thanks.
Alecsandru Cocarla
Ranch Hand

Joined: Feb 29, 2008
Posts: 158
Ok, so here's the new version.

What's new:
- More classes
- Improved design
- Improved logging
- Not all the states were converted to new ThreadSequence implementations, because that would be (in my opinion) over-engineering in this case.
- I could not use Runnable for the SequenceStep because I need to access both join() and internal state within other threads.









A short user guide:
1. Run the test
2. Investigate the output. You should:
- not have a message like "TSxxx locked AA" unless another TS already issued the "TSyyy unlocked AA" (except the first lock, of course). An amendment - there are cases when concurrent writing to sysout will mess up the order of these two outputs. If they are close (like one after the other but in the wrong order, and this only happens once in a while, then you're probably safe. However, you should also check your logs and see what exactly happened.
- not have messages like "TSxxx read/updated/deleted AA" after another TS deleted the same record (unless you reuse deleted records and some other TS already created a new record in the same place).

Have fun with it and come back with feedback

[ November 01, 2008: Message edited by: Alecsandru Cocarla ]
[ November 01, 2008: Message edited by: Alecsandru Cocarla ]
Alecsandru Cocarla
Ranch Hand

Joined: Feb 29, 2008
Posts: 158
User guide continued...
How to disambiguate when the amendment at point 2 mentioned before happens.

This a sample of an ambiguous output that I received:
TS049 unlocking 14 - here it starts
TS158 unlocked 33
TS156 locked 12
TS156 deleting 12
TS044 unlocked 34
TS241 locked 16
TS241 updating 16
TS046 unlocked 20
TS132 locked 34
TS132 updating 34
TS016 deleted 43
TS016 unlocking 43
TS100 locked 20
TS100 deleting 20
TS082 locked 14 - another TS locked my record? It's not unlocked yet
TS082 deleting 14 - what??? It even deleted it
TS055 updated 22
TS055 unlocking 22
TS049 unlocked 14 - S**t, that's a little too late!!

What I did - I added sysouts in my locking code (immediately after recordLock.lock() and right before recordLock.unlock(), in order to see what exactly what happened.

This is what happened in fact:

TS049 unlocking 14 - here it starts
----unlocking 34
----unlocked 34
TS158 unlocked 33
----locked 12
----locked 16
TS156 locked 12
TS156 deleting 12
TS044 unlocked 34
----unlocking 20
----unlocked 20
----locked 34
TS241 locked 16
TS241 updating 16
----locked 20
----unlocking 14 - very well
----unlocked 14 - now it's unlocked
TS046 unlocked 20
TS132 locked 34
TS132 updating 34
TS016 deleted 43
TS016 unlocking 43
TS100 locked 20
----locked 14 - it's already unlocked, so it can lock
TS100 deleting 20
TS082 locked 14 - it's already unlocked, so it can lock
TS082 deleting 14 - it's locked, can delete
TS055 updated 22
TS055 unlocking 22
TS049 unlocked 14 - the output is late, but the sysouts from locking methods really showed me what went on.
[ November 21, 2008: Message edited by: Alecsandru Cocarla ]
Fola Fadairo
Ranch Hand

Joined: Feb 16, 2004
Posts: 35
Hello Alesc,
I have 2 questions.

1. The conditions, you use in the constructors for Lockless and Lockable Thread Sequences.



I think the the conditional operator should be 'OR' instead of 'AND'

2. Why do you exclude the CREATE_MODE from the Lockable sequence? I expect that creating a new record entails
a) Obtaining a write lock on the database.
b) Writing to the database.
c) Releasing the write lock.

Thanks.
Alecsandru Cocarla
Ranch Hand

Joined: Feb 29, 2008
Posts: 158
Originally posted by Fola Fadairo:

1. The conditions, you use in the constructors for Lockless and Lockable Thread Sequences.


I think the the conditional operator should be 'OR' instead of 'AND'

The != sign makes the difference. So, if the mode is not one of the expected ones, an exception is thrown.
You can run the tests, and you'll see it works.

Originally posted by Fola Fadairo:

2. Why do you exclude the CREATE_MODE from the Lockable sequence? I expect that creating a new record entails
a) Obtaining a write lock on the database.
b) Writing to the database.
c) Releasing the write lock.

My create() method signature from the SUN provided interface is:

public int create(String[] data) throws DuplicateKeyException;

No cookie involved for create. This means no lock is required either. Also, no record number is involved, which means I wouldn't know what record to lock. Only update() and delete() require locking. And this is ok, because the only thing you can do with a "creatable" (meaning already deleted or non-existent yet) record is to create() (you can't delete, update or read where a record should be created). After a record is created, no other create() operation can occur in the same place, unless you first delete the record. In conclusion, there's no way two clients create the same record at the same time, or one thread read/delete/update while some other thread is creating.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Data class multithreaded load test (UB1.1.2)