java 同步和静态同步有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1536064/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between synchronized and static synchronized?
提问by Andrzej Doyle
For a travel booking web application, where there are 100 concurrent users logged in, should ticket booking and generating an "E-Ticket Number" be implemented by a "synchronized" or a "static synchronized" method?
对于有 100 个并发用户登录的旅行预订 Web 应用程序,应该通过“同步”还是“静态同步”方法来实现订票和生成“电子票号”?
回答by Jon Skeet
Well, are you aware of the difference between a static method and an instance method in general?
那么,您是否知道静态方法和实例方法之间的一般区别?
The only difference that synchronizedmakes is that before the VM starts running that method, it has to acquire a monitor. For an instance method, the lock acquired is the one associated with the object you're calling the method on. For a static method, the lock acquired is associated with the type itself - so no other threads will be able to call any other synchronized static methods at the same time.
唯一的区别synchronized是在 VM 开始运行该方法之前,它必须获得一个监视器。对于实例方法,获取的锁是与调用该方法的对象相关联的锁。对于静态方法,获取的锁与类型本身相关联——因此没有其他线程能够同时调用任何其他同步静态方法。
In other words, this:
换句话说,这:
class Test
{
static synchronized void Foo() { ... }
synchronized void Bar() { ... }
}
is roughlyequivalent to:
是大致等效于:
class Test
{
static void Foo()
{
synchronized(Test.class)
{
...
}
}
void Bar()
{
synchronized(this)
{
...
}
}
}
Generally I tend not to use synchronized methods at all - I prefer to explicitly synchronize on a private lock reference:
通常我根本不使用同步方法——我更喜欢在私有锁引用上显式同步:
private final Object lock = new Object();
...
void Bar()
{
synchronized(lock)
{
...
}
}
You haven't provided nearly enough information to determine whether your method should be a static or instance method, or whether it should be synchronized at all. Multithreading is a complex issue - I strongly suggest that you read up on it (through books, tutorials etc).
您没有提供足够的信息来确定您的方法应该是静态方法还是实例方法,或者它是否应该被同步。多线程是一个复杂的问题 - 我强烈建议您阅读它(通过书籍、教程等)。
回答by Andrzej Doyle
Jon's answer covers the difference hinted at in your question title.
乔恩的回答涵盖了您问题标题中暗示的差异。
However, I would say that neithershould be used for generating a ticket number. On the assumption that these are being stored in a database, somewhere - the database should be responsible for generating the number when you insert the new record (presumably by an autoincrementing primary key, or something similar).
但是,我想说两者都不应该用于生成票号。假设这些存储在数据库中的某个地方 - 数据库应该负责在您插入新记录时生成数字(大概是通过自动递增的主键或类似的东西)。
Failing that, if you mustgenerate the number within Java code, I suspect that the synchronisation overhead might be quite noticeable with 100 concurrent users. If you are running on Java 1.5 or later, I'd use a java.util.concurrent.AtomicIntegerto get the ticket number, which you can simply call as
否则,如果您必须在 Java 代码中生成数字,我怀疑 100 个并发用户的同步开销可能会非常明显。如果您在 Java 1.5 或更高版本上运行,我会使用 ajava.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();
}
This gives you the concurrent global uniqueness you need in a much more efficient fashion than synchronizing every time you need an integer.
与每次需要整数时进行同步相比,这以更有效的方式为您提供了所需的并发全局唯一性。

