Source:
<code>public synchronized void sendNotification(final T notification) { <START> final ApnsConnection<T> apnsConnection = this; <END> if (!this.hasCompletedHandshake()) { throw new IllegalStateException(String.format("%s has not completed handshake.", this.name)); } this.connectFuture.channel().eventLoop().execute(new Runnable() { public void run() { final SendableApnsPushNotification<T> sendableNotification = new SendableApnsPushNotification<T>(notification, apnsConnection.sequenceNumber++); log.trace("{} sending {}", apnsConnection.name, sendableNotification); apnsConnection.pendingWriteCount += 1; apnsConnection.connectFuture.channel().writeAndFlush(sendableNotification).addListener(new GenericFutureListener<ChannelFuture>() { public void operationComplete(final ChannelFuture writeFuture) { if (writeFuture.isSuccess()) { log.trace("{} successfully wrote notification {}", apnsConnection.name, sendableNotification.getSequenceNumber()); if (apnsConnection.rejectionReceived) { apnsConnection.listener.handleUnprocessedNotifications(apnsConnection, java.util.Collections.singletonList(notification)); } else { apnsConnection.sentNotificationBuffer.addSentNotification(sendableNotification); } } else { log.trace("{} failed to write notification {}", apnsConnection.name, sendableNotification, writeFuture.cause()); apnsConnection.listener.handleWriteFailure(apnsConnection, notification, writeFuture.cause()); } apnsConnection.pendingWriteCount -= 1; assert apnsConnection.pendingWriteCount >= 0; if (apnsConnection.pendingWriteCount == 0) { synchronized (apnsConnection.pendingWriteMonitor) { apnsConnection.pendingWriteMonitor.notifyAll(); } } } }); } }); }</code><technical_language>a confused this, knowing full code. synchronize spinning a thread anyway? duplicate notification? expecting thread synchronized well</technical_language>

Target:
public synchronized void sendNotification(final T notification) { final ApnsConnection<T> apnsConnection = this; if (!this.handshakeCompleted) { throw new IllegalStateException(String.format("%s has not completed handshake.", this.name)); } this.connectFuture.channel().eventLoop().execute(new Runnable() { public void run() { final SendableApnsPushNotification<T> sendableNotification = new SendableApnsPushNotification<T>(notification, apnsConnection.sequenceNumber++); log.trace("{} sending {}", apnsConnection.name, sendableNotification); apnsConnection.pendingWriteCount += 1; apnsConnection.connectFuture.channel().writeAndFlush(sendableNotification).addListener(new GenericFutureListener<ChannelFuture>() { public void operationComplete(final ChannelFuture writeFuture) { if (writeFuture.isSuccess()) { log.trace("{} successfully wrote notification {}", apnsConnection.name, sendableNotification.getSequenceNumber()); if (apnsConnection.rejectionReceived) { apnsConnection.listener.handleUnprocessedNotifications(apnsConnection, java.util.Collections.singletonList(notification)); } else { apnsConnection.sentNotificationBuffer.addSentNotification(sendableNotification); } } else { log.trace("{} failed to write notification {}", apnsConnection.name, sendableNotification, writeFuture.cause()); apnsConnection.listener.handleWriteFailure(apnsConnection, notification, writeFuture.cause()); } apnsConnection.pendingWriteCount -= 1; assert apnsConnection.pendingWriteCount >= 0; if (apnsConnection.pendingWriteCount == 0) { synchronized (apnsConnection.pendingWriteMonitor) { apnsConnection.pendingWriteMonitor.notifyAll(); } } } }); } }); }