对于旅行预订Web应用程序,其中有100个并发用户登录,应该订票并生成“电子客票号码”由“同步”或“静态同步”的方法来实现?
Answer 1:
那么,你知道静态方法和一般的实例方法之间的区别?
该唯一的区别synchronized
使得在于VM开始运行该方法之前,它具有获取监视器。 对于一个实例方法,获取了锁是你调用方法的对象相关联的一个。 为一个静态方法,获取的锁与该类型本身相关联 - 因此没有其他线程将能够调用任何其他同步静态方法在同一时间。
换句话说,这样的:
class Test
{
static synchronized void Foo() { ... }
synchronized void Bar() { ... }
}
大致等同于:
class Test
{
static void Foo()
{
synchronized(Test.class)
{
...
}
}
void Bar()
{
synchronized(this)
{
...
}
}
}
一般来说,我往往不会在所有使用synchronized方法 - 我更喜欢在一个私人锁参考显式同步:
private final Object lock = new Object();
...
void Bar()
{
synchronized(lock)
{
...
}
}
您没有提供信息不足以判断你的方法是否应该是一个静态或实例方法,还是应该在所有的同步。 多线程是一个复杂的问题 - 我强烈建议你读了它(通过书籍,教程等)。
Answer 2:
乔恩的回答涵盖了在你的问题的标题暗示的差异。
但是,我要说的是不应被用于产生票号。 在这些被存储在数据库中的假设,某个地方 - 数据库应当你插入新记录(比如通过自动增量的主键,或者类似的东西)是负责生成的数量。
如果做不到这一点,如果你必须生成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();
}
这可以为您以更有效的方式需要比同步每次你需要一个整数时并发的全球唯一性。
文章来源: What is the difference between synchronized and static synchronized?