id的Web服务增量变量使用单例/同步

时间:2013-03-19 17:49:14

标签: java web-services design-patterns singleton primary-key

我正在实施一个用于攻击一个数据库的webservice女巫。 我需要为我存储的对象生成ID,而我不知道最好的方法是什么。 我需要增加一个INT。

显然,网络服务必须同时用于这么多人,也许各种各样。

那么,什么是一个很好的解决方案?

单/同步??

我认为这是我所知道的唯一方式,也许还有其他更好的方式。

如果你能给我一个例子,我将非常感激。

提前感谢!

3 个答案:

答案 0 :(得分:0)

使用synchronize块来实现此目的。在synchronized块中,只有一个线程可以进入其中。

JVM保证Java同步代码一次只能由一个线程执行。

答案 1 :(得分:0)

同步有可怕的开销。如果您只需要增量计数器,则可以使用AtomicLong's incrementAndGet()。将AtomicLong放在Singleton中以获得服务器范围的访问权限。

修改:部分代码示例:

import java.util.concurrent.atomic.AtomicLong;

public class AtomicIdGenerator
{
    private static class SingletonHolder
    {
        public static final AtomicIdGenerator instance = new AtomicIdGenerator();
    }

    public static AtomicIdGenerator getInstance()
    {
        return SingletonHolder.instance;
    }

    private AtomicLong mIdGenerator = null;

    private AtomicIdGenerator()
    {
        mIdGenerator = new AtomicLong();
    }

    private AtomicLong getGenerator()
    {
        return mIdGenerator;
    }

    public long getNewId()
    {
        return getGenerator().incrementAndGet();
    }
}

用法示例很简单:

long tNewId = AtomicIdGenerator.getInstance().getNewId();

这将是线程安全的,并且没有任何同步开销。如果您预见自己将来会处理大量并发用例,java.util.concurrent包会为您的用例提供大量经过实战验证的实现。

答案 2 :(得分:0)

你可以这样做。我已经做了一段时间,它基于PostgreSql和iBatis,但你可以得到这个想法。

public class Sequence implements Serializable {
    private static final long serialVersionUID = 7526471155622776147L;
    private String name  = null;
    private int nextId = 0;

    public Sequence () {
    }

    public Sequence (String name, int nextId) {
        this.name = name;
        this.nextId = nextId;
    }

    public final String getName () {
        return name;
    }

    public final void setName (String name) {
        this.name = name;
    }

    public final int getNextId () {
        return nextId;
    }

    public final void setNextId (int nextId) {
        this.nextId = nextId;
    }

}


public class SequenceSqlMapDao extends SqlMapClientDaoSupport implements SequenceDao {

  /**
   * This is a generic sequence ID generator that is based on a database
   * table called 'SEQUENCE', which contains two columns (NAME, NEXTID).
   * <p/>
   * This approach should work with any database.
   *
   * @param name The name of the sequence.
   * @return The Next ID
   * @
   */
  public final synchronized int getNextId(String name) {
    Sequence sequence = new Sequence(name, -1);
    //Sequence sequence = new Sequence();
    sequence = (Sequence) getSqlMapClientTemplate ().queryForObject("getSequence", sequence);
    if (sequence == null) {
            try {
                throw new IllegalArgumentException("Error: SHOOT! A null sequence was returned from the database (could not get next " + name + " sequence).");
            } catch (Exception ex) {
                Logger.getLogger(SequenceSqlMapDao.class.getName()).log(Level.SEVERE, null, ex);
            }
    }
    Object parameterObject = new Sequence(name, sequence.getNextId() + 1);
    getSqlMapClientTemplate ().update("updateSequence", parameterObject);
    int nextId = sequence.getNextId();

    parameterObject  = null;
    sequence = null;

    return nextId;
  }

}

如果没有别的,那么这与数据库无关。您仍然需要在Web服务中公开该方法。 PS - 我忘记了从哪里得到这个,否则我会赞美合适的来源。