NinjaStars
NinjaStars

Reputation: 253

Java Threading with MYSQL puzzled

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

Answers (3)

Trying
Trying

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

Dawood ibn Kareem
Dawood ibn Kareem

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

Sotirios Delimanolis
Sotirios Delimanolis

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

Related Questions