Thread monitoring for database query
Hi,
I need to be able to store a database query in a thread. This means that the entire query from executing to return should take place in this thread (as well as connection etc). I would then like to know when it have finished its work so i can carry on some more porcessing.
I tried doing this with two threads, one to do the work and the other to 'watch' and then tell me when is is done. However,i errors 'every now and again' to which i can attribute to my thread structure not working properly.I am using a synchronised class and code post the code if anyone wishes to see it, however, i would appreciate it if someone could give me a basic structure to how i can go about this so that i do not get these 'random' errors.
Thanks Rudy
[793 byte] By [
rudyard] at [2007-9-30 11:10:19]

Post some simplified code of what you are trying to do.Remember to use the code tage (see formatting help)
Thanks for the response.
The class below is the 'Monitor class'
public class BPSGotData {
private static boolean successful = false;
public synchronized void setSuccessful(boolean successful){
this.successful = successful;
System.out.println("SetSuccess " + this.successful);
notify();
}
public synchronized void waitForData(){
System.out.println("Waiting");
while(successful == false){
try{
wait();
}catch(InterruptedException ie){
ie.printStackTrace();
}
}
successful = false;
}
}
Then i have one thread class that is doing work
//this is the method that sets the monitor to true
//it is call an adapter class
public class BPSGenericDataRetrievalThread extends Thread{
//..more methods
public void getTableModel(String sproc, Vector params){
adapter.executeQuery(sproc, params);
gotData.setSuccessful(true);
}
}
this is the class that is waiting
BPSGenericDataRetrievalThread genericDataRetrievalThread = null;
genericDataRetrievalThread = new BPSGenericDataRetrievalThread(database, gotData, sproc, params);
genericDataRetrievalThread.start();
dataThread.start();
gotData.waitForData();
//then do another call using diferent params
genericDataRetrievalThread = new BPSGenericDataRetrievalThread(database, gotData, sproc, params);
dataThread.start();
gotData.waitForData();
//then do another call using diferent params....
But i get intermittent out of bounds exceptions, from a vector class and no other info based on any of my classes.
Thanks
Rudy
this is the exception that is generated
java.lang.ArrayIndexOutOfBoundsException: 3 >= 3
at java.util.Vector.elementAt(Vector.java:431)
at javax.swing.table.DefaultTableColumnModel.getColumn(DefaultTableColumnModel.java:277)
at javax.swing.plaf.basic.BasicTableHeaderUI.paint(BasicTableHeaderUI.java:337)
at javax.swing.plaf.ComponentUI.update(ComponentUI.java:142)
at javax.swing.JComponent.paintComponent(JComponent.java:541)
at javax.swing.JComponent.paint(JComponent.java:808)
at javax.swing.JComponent.paintWithOffscreenBuffer(JComponent.java:4795)
at javax.swing.JComponent.paintDoubleBuffered(JComponent.java:4748)
at javax.swing.JComponent._paintImmediately(JComponent.java:4692)
at javax.swing.JComponent.paintImmediately(JComponent.java:4495)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:410)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:117)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:178)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:454)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:145)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:137)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:100)
Thanks forthe help
Rudy
Okay -
I have an idea. Withut fully implementing your code, mind you.
If looks like you're having problems with concurrent access to your Vector.
A Vector is, of course, a Collection and a List (interfaces) - these are not thread safe. To make them thread safe, you need to "wrap" them.
<lifted from JavaDocs>
public static Collection synchronizedCollection(Collection c)
Returns a synchronized (thread-safe) collection backed by the specified collection. In order to guarantee
serial access, it is critical that all access to the backing collection is accomplished through the returned
collection.
It is imperative that the user manually synchronize on the returned collection when iterating over it:
Collection c = Collections.synchronizedCollection(myCollection);
...
synchronized(c) {
Iterator i = c.iterator(); // Must be in the synchronized block
while (i.hasNext())
foo(i.next());
}
Failure to follow this advice may result in non-deterministic behavior.
The returned collection does not pass the hashCode and equals operations through to the backing
collection, but relies on Object's equals and hashCode methods. This is necessary to preserve the
contracts of these operations in the case that the backing collection is a set or a list.
The returned collection will be serializable if the specified collection is serializable.
Parameters:
c - the collection to be "wrapped" in a synchronized collection.
Returns:
a synchronized view of the specified collection.
</lifted from JavaDocs>
Give your Vector a wrapper and see if that solves your problem.
+M
Hi,
Problem is, is that i am not using a vector that is being shared. The only vector that i am using is the one in my JDBCAdapter class, but this is would not have concurrent access as they are different intances of a class, namely the genericDataRetrievalThread class or is this not true.
If is it not, how would i go about wrapping access to the following
// Get all rows.
rows = new Vector();
while (resultSet.next()) {
Vector newRow = new Vector();
for (int i = 1; i <= getColumnCount(); i++) {
newRow.addElement(resultSet.getObject(i));
}
rows.addElement(newRow);
}
this code is in my adapter class used bu my table as its table model.
Thanks a lot for your help
Rudy