1

I am implementing a webservice witch is used to attack one DB. i need to generate ID for objects that i store and i don't know what's the best way to do it. i need to increment a INT.

Obviously the webservice must to be used for so much people and maybe various at same time.

so, what's is a good solution?

singleton/synchronize??

i think is the only way i know, maybe there are others better.

if u can show me one example it will be very appreciated.

thanks in advance!

4

3 回答 3

0

Use synchronize block to achieve this. In synchronized block only one thread can enter inside it.

JVM guarantees that Java synchronized code will only be executed by one thread at a time.

于 2013-03-19T17:49:58.630 回答
0

同步有可怕的开销。如果您只需要一个增量计数器,您可以使用AtomicLong 的 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包为您的用例提供了许多经过实战验证的实现。

于 2013-03-19T18:01:29.060 回答
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;
  }

}

如果不出意外,这与数据库无关。您仍然必须在您的网络服务中公开该方法。PS - 我忘记了我从哪里得到的,否则我会归功于适当的来源。

于 2013-03-19T18:04:54.587 回答