What is the difference between synchronized and st

2019-01-14 14:49发布

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?

2条回答
太酷不给撩
2楼-- · 2019-01-14 15:08

Well, are you aware of the difference between a static method and an instance method in general?

The only difference that synchronized makes 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.

In other words, this:

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

    synchronized void Bar() { ... }
}

is roughly equivalent 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).

查看更多
smile是对你的礼貌
3楼-- · 2019-01-14 15:22

Jon's answer covers the difference hinted at in your question title.

However, I would say that neither should 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 must generate 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.AtomicInteger to get the ticket number, which you can simply call as

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.

查看更多
登录 后发表回答