多线程头痛 Java返回值

问题描述

| 大家好,我有以下内容
class a extends Thread    
{
    public synchronized BigInteger getUniqueID()
    {
        BigInteger aUniqueID = new BigInteger(getUniqueKeyFromDatabase);
        return aUniqueID;
    }   
}

class b extends a
{
    public run()
    {
        BigInteger uniquieID = getUniqueID();       
        // store UniqueID in another database table with other stuff
     }
}
我得到的是存储在数据库表中的重复唯一ID。我假设是因为在此多线程环境中更改了uniqieID。 我显然在某个地方犯了可怕的错误,我想我不应该以这种方式返回值。或者应该根据getUniqueID方法的响应将uniqueID定义为新的BigInteger。 任何帮助将不胜感激,因为我脆弱的头脑现在已经变形了! 干杯 艾伦     

解决方法

ѭ1是(来自JavaDocs)   不可变的任意精度整数 这样就排除了变异BigInteger对象的任何人。我去找ѭ2     ,您的getUniqueKeyFromDatabase()必须是不会两次返回相同值的方法。其他一切都没有关系。 每个线程都有自己的局部变量副本,因为它们不是共享的。 顺便说一句:不要扩展Thread,它的错误做法经常导致混乱。     ,您的问题是因为您没有真正进行任何同步。类A中的getUniqueID()方法在其自己的隐式监视器上同步。但这意味着每次您创建一个新线程时,您都将自己同步每个线程。那有意义吗 ? 您需要在某些共享变量上进行同步。一个简单的方法来说明这一点(但实际上实际上不使用它):在下面的示例中,所有线程都在同一个对象(共享的static)上进行同步。
class A extends Thread {

    static Object shared = new Object();

    public BigInteger getUniqueID()
    {
       synchronize (shared) {
         BigInteger aUniqueID = new BigInteger(getUniqueKeyFromDatabase);
         return aUniqueID;
       }
    }

}
    ,
getUniqueID()
synchronized
修饰符可能毫无意义,因为您不在那里修改任何状态。它也不保护ѭ6,因为它在实例上同步。这意味着每个线程在运行时都不会与其他线程同步。 你可以尝试
public BigInteger getUniqueID() {
   synchronized (a.class) {
      BigInteger aUniqueID = new BigInteger(getUniqueKeyFromDatabase);
      return aUniqueID;
   } 
}
更适合您。如果是这样,您应该考虑数据库的设计(或
getUniqueKeyFromDatabase
中发生的一切)。同步化实际上应该由数据库完成,而不是由客户端代码完成。     ,您必须对返回唯一ID的方法有疑问。为了确保每个对象的ID的唯一性,请使用以下示例,例如在类a中。 PS:班级名称应以大写字母开头。就像@Peter Lawrey所建议的那样,实现Runnable而不是扩展Thread。
    private static int nextId = 0;
    protected int id;

    public a(){
       this.id = getNextId();
    }
    private static int getNextId(){
        return nextId++;
    }