同步和静态同步有什么区别?

时间:2009-10-08 07:04:13

标签: java multithreading synchronization

对于旅行预订网络应用程序,其中有100个并发用户登录, 机票预订和生成“电子机票号码”是通过“同步”还是“静态同步”方法实现的?

2 个答案:

答案 0 :(得分:20)

嗯,您是否了解静态方法和实例方法之间的区别?

synchronized的唯一区别是,在VM开始运行该方法之前,它必须获取监视器。对于实例方法,获取的锁是与您调用方法的对象关联的锁。对于静态方法,获取的锁与类型本身相关联 - 因此没有其他线程可以同时调用任何其他同步的静态方法。

换句话说,这个:

class Test
{
    static synchronized void Foo() { ... }

    synchronized void Bar() { ... }
}

大致等同于:

class Test
{
    static void Foo()
    {
        synchronized(Test.class)
        {
            ...
        }
    }

    void Bar()
    {
        synchronized(this)
        {
            ...
        }
    }
}

通常我根本不会使用同步方法 - 我更喜欢在私有锁引用上显式同步:

private final Object lock = new Object();

...

void Bar()
{
    synchronized(lock)
    {
        ...
    }
}

您尚未提供足够的信息来确定您的方法应该是静态方法还是实例方法,或者它是否应该同步。多线程是一个复杂的问题 - 我强烈建议你阅读它(通过书籍,教程等)。

答案 1 :(得分:3)

Jon的答案涵盖了问题标题中暗示的差异。

但是,我会说 不应该用于生成票号。假设这些存储在数据库中的某个地方 - 数据库应该负责在插入新记录时生成数字(可能是通过自动增量主键或类似的东西)。

如果你失败了,如果必须在Java代码中生成数字,我怀疑100个并发用户的同步开销可能非常明显。如果您在Java 1.5或更高版本上运行,我会使用java.util.concurrent.AtomicInteger来获取票号,您可以简单地将其称为

private static final AtomicInteger ticketSequence;

static
{
    final int greatestTicket = getHighestExistingTicketNumber(); // May not be needed if you can start from zero each time
    ticketSequence = new AtomicInteger(greatestTicket + 1);
}

public /*static*/ int getNextTicketNumber()
{
    return ticketSequence.incrementAndGet();
}

这为您提供了所需的并发全局唯一性,而不是每次需要整数时都需要同步。