Reputation: 253
I am very puzzled by the behavior of MySQL and java threading. I declare this as synchronized and the results I get are clashing. That means that more than one thread is accessing the same function at the same time. This code segment is in the runnable class. MachineID is the thread id in the order with which it was invoked in the for loop. (It is jsut a number from 1 to 100).
I don't think the table is required information to
This is the output I get
144 18
144 17
144 11
144 13
144 10
144 9
public synchronized int getRow() throws SQLException{
String query="SELECT * FROM Searches WHERE checked='0'";
ResultSet results = this.database.executeQuery(query);
int id=0;
if(results.next()){
id=results.getInt(1);
System.out.println(id+" "+this.machineID);
query = "UPDATE Searches SET checked='1' WHERE ID_num='"+id+"'";
System.out.println(this.database.executeUpdate(query));
}
return id;
}
public void run() {
int id=getRow();
if (id!=0) {
}
}
this is where I invoke my threads
for (int i = 0; i < verifier.length; i++) {
verifier[i]=new Thread(new Verifier(main.database,i+1));
verifier[i].start();
}
Upvotes: 1
Views: 113
Reputation: 14278
No synchronization is happening at all it's is similar to
synchronize(this)
And the same instance is not shared across the threads so there is no synchronization happening at all.
So you need to share a lock object across the Runnable
instances i.e. Verifier
in constructer like:
public class Verifier implements Runnable{
private final Object lock;
public Verifier(Object lock){
this.lock=lock;
}
Than you can synchronize on the lock like:
synchronize(lock)
else you can synchronize on the class object as well:
synchronize(Verifier.class)
Upvotes: 0
Reputation: 79807
Sotirios has hit the nail on the head. But instead of having a new variable to lock on, I would use just a single Verifier
, and call it from multiple threads. So you'll have
Verifier oneVerifier = new Verifier(main.database, 1);
for (int i = 0; i < verifier.length; i++) {
verifier[i]=new Thread(oneVerifier);
verifier[i].start();
}
Note - I don't know what that second argument to the Verifier
constructor is supposed to be. Chances are, you don't actually need it, but since you don't actually show the constructor, I thought I'd leave it in.
Upvotes: 0
Reputation: 279880
Assuming the getRow()
method belongs to the Verifier
class, then there is no blocking going on. When you declare synchronized
on a method, it is equivalent to synchronizing on the instance itself. However, you are spawning a new Verifier
instance for each Thread
. Each of those is synchronizing on themselves so none block any of the others.
Consider sharing a Lock
object with each instance of Verifier
or synchronizing on a shared object.
Object lock = new Object();
for (int i = 0; i < verifier.length; i++) {
verifier[i]=new Thread(new Verifier(main.database,i+1, lock));
verifier[i].start();
}
...
public int getRow() throws SQLException{
synchronized(lock) {
...
}
}
Upvotes: 4