A question to the community: IO inside synchronized methods/blocks

lei yu yuulei12 at gmail.com
Tue Jan 23 06:53:49 UTC 2018


Hi,

Performing blocking IO inside synchronized methods/blocks is not a common paradigm in our implementation, but they do exist everywhere, especially in many legacy applications.

Many of our RPC services were built on Netty, which manages IO heavily via j.u.c, coroutine works well in most cases, but we do have some exceptions even in Netty...

Here is example:
The common usage of creating TCP connection in Netty is by calling bootstrap.connect().sync(), bootstrap.connect() returns a DefaultPromise [1] Object, which is using  ObjectMonitor. if the application are creating lots of short connections, it might have big impact on performance. 

The following example demonstrates how we can change DefaultPromise to use j.u.c, it is straightforward.

```
public class DefaultPromise<V> extends AbstractFuture<V> implements Promise<V> {
    @Override
    public Promise<V> await() throws InterruptedException {
      ....

        synchronized (this) {
            while (!isDone()) {
                checkDeadLock();
                incWaiters();
                try {
                    wait();
                } finally {
                    decWaiters();
                }
            }
        }
        return this;
    }
}
```
could be changed to
```
public class DefaultPromise<V> extends AbstractFuture<V> implements Promise<V> {

    private Lock lock = new ReentrantLock();
    private Condition cond = lock.newCondition();

    @Override
    public Promise<V> await() throws InterruptedException {
      ....

        lock.lock()
        try {
            while (!isDone()) {
                checkDeadLock();
                incWaiters();
                try {
                    cond.await();
                } finally {
                    decWaiters();
                }
            }
        } finally {
            lock.unlock();
        }
        return this;
    }
}
```
Very simple on above piece of code change, but unfortunately in real world, it is very hard to require our developers to change their code to use j.u.c, 
it will involve lots of engineering efforts: synchronized does exist everywhere, some uses of them actually are  not obvious, e.g. in <clinit>, classLoading cases etc.

That is important reason why Alibaba' coroutine implementation was designed for synchronized/Object.wait()'s support:)

[1] https://github.com/netty/netty/blob/4.1/common/src/main/java/io/netty/util/concurrent/DefaultPromise.java <https://github.com/netty/netty/blob/4.1/common/src/main/java/io/netty/util/concurrent/DefaultPromise.java>

Yu, Lei


More information about the loom-dev mailing list