我对MySQL和java线程的行为感到非常困惑。我声明这是同步的,我得到的结果是冲突。这意味着多个线程同时访问同一个函数。此代码段位于runnable类中。 MachineID是在for循环中调用它的顺序中的线程id。 (它是1到100之间的数字)。
我不认为该表是必需的信息
这是我得到的输出
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) {
}
}
这是我调用我的线程的地方
for (int i = 0; i < verifier.length; i++) {
verifier[i]=new Thread(new Verifier(main.database,i+1));
verifier[i].start();
}
答案 0 :(得分:4)
假设getRow()
方法属于Verifier
类,则不会发生阻塞。在方法上声明synchronized
时,它等同于在实例上进行同步。但是,您为每个Verifier
生成了一个新的Thread
实例。每个人都在同步自己,所以没有人阻止任何其他人。
考虑与Lock
的每个实例共享Verifier
对象或在共享对象上进行同步。
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) {
...
}
}
答案 1 :(得分:0)
Sotirios已经击中了头部。但是我没有使用新的变量来锁定,而是只使用一个Verifier
,并从多个线程调用它。所以你会有
Verifier oneVerifier = new Verifier(main.database, 1);
for (int i = 0; i < verifier.length; i++) {
verifier[i]=new Thread(oneVerifier);
verifier[i].start();
}
注意 - 我不知道Verifier
构造函数的第二个参数应该是什么。有可能,你实际上并不需要它,但由于你实际上并没有显示构造函数,我以为我会留下它。
答案 2 :(得分:0)
根本没有同步发生,它类似于
synchronize(this)
并且不会在线程之间共享同一个实例,因此根本不会发生同步。
因此,您需要在Runnable
实例之间共享锁定对象,例如Verifier
在构造函数中:
public class Verifier implements Runnable{
private final Object lock;
public Verifier(Object lock){
this.lock=lock;
}
比你可以在锁上同步:
synchronize(lock)
否则你也可以在类对象上同步:
synchronize(Verifier.class)