Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why external synchronization is faster than internal one?

In Collection framework, why is external synchronization is faster than internal one(Vector, HashTable etc)? Even though they both use same mechanism?

What exactly meaning of internal and external synchronizations and how do they differ from each other?

It is really helpful if someone can explain with examples.

like image 787
Rajeev Avatar asked Sep 27 '13 16:09

Rajeev


2 Answers

What exactly meaning of internal and external synchronizations and how do they differ from each other?

External synchronization is when the caller (you) use the synchronized keyword or other locks to protect against another class being accessed by multiple threads. It is usually used if the class in question is not synchronized itself -- SimpleDateFormat is a prime example. It can also be used if you need signaling between threads -- even when dealing with a concurrent collection.

why is external synchronization is faster than internal one(Vector, HashTable etc)? Even though they both use same mechanism?

External synchronization is not necessarily faster. Typically a class can determine precisely when it needs to synchronize around a critical section of code instead of the caller wrapping all method calls in a synchronized block.

If you are talking about the general recommendation to not use Vector and HashTable and instead use the Collections.synchronizedList(...) or synchronizedMap(...) methods, then this is because Vector and HashTable are seen as old/old-of-date classes. A wrapped ArrayList or HashMap is seen as a better solution.

Sometimes as @Chris pointed out, external synchronization can be faster when you need to make a number of changes to a class one after another. By locking externally once and then performing multiple changes to the class, this works better than each change being locked internally. A single lock being faster than multiple lock calls are made in a row.

It is really helpful if someone can explain with examples.

Instead of Vector, people typically recommend a wrapped ArrayList as having better performance. This wraps the non-synchronized ArrayList class in a wrapper class which external synchronizes it.

List<Foo> list = Collections.synchronizedList(new ArrayList<Foo>());

In terms of internal versus external in general, consider the following class that you want to allow multiple threads to use it concurrently:

public class Foo {
    private int count;
    public void addToCount() {
        count++;
        log.info("count increased to " + count);
    }
}

You could use external synchronization and wrap every call to addToCount() in a synchronized block:

synchronized (foo) {
   foo.addToCount();
}

Or the class itself can use internal synchronization and do the locking for you. This performs better because the logger class does not have to be a part of the lock:

public void addToCount() {
    int val;
    synchronized (this) {
       val = ++count;
    }
    // this log call should not be synchronized since it does IO
    log.info("count increased to " + val);
}

Of course, the Foo class really should use an AtomicInteger in this case and take care of its own reentrance internally:

private final AtomicInteger count = new AtomicInteger(0);
public void addToCount() {
    int val = count.incrementAndGet()
    log.info("count increased to " + val);
}
like image 106
Gray Avatar answered Dec 16 '22 14:12

Gray


Let's say you work in a bank. Every time you need to use the safe, it needs to be unlocked, and then re-locked when you're done using it.

Now let's say that you need to carry 50 boxes into the safe. You have two options:

  1. Carry each box over individually, opening and closing the (extremely heavy) door each time
  2. Lock the front door to the bank and leave the vault open, make 50 trips without touching the internal vault door

Which one is faster? (The first option is internal synchronization, the second option is external synchronization.)

like image 40
Chris Eberle Avatar answered Dec 16 '22 15:12

Chris Eberle