public NotificationRecord[] fetchNotifications() {
        if (notifications.isEmpty()) {
            //Need to have a timedOut flag because of possible spurious wakeup
            final long timedOut = System.nanoTime() + deliveryInterval;

            synchronized (waitFlag) {
                while (notifications.isEmpty() && (System.nanoTime() < timedOut)) {
                    try {
                        waitFlag.wait(deliveryInterval / 1000000L);
                    } catch (InterruptedException e) {
                        //keep waiting until conditions aren't met anymore
                    }
                }
            }
        }

        NotificationRecord[] fetchedNotifications = null;

        if (!notifications.isEmpty()) {
            synchronized (notifications) {
                fetchedNotifications = notifications.toArray(new NotificationRecord[notifications.size()]);
                notifications.clear();
            }
        }

        //Update the timestamp
        lastAccessTimeStamp = System.nanoTime();

        return fetchedNotifications;
    }
public NotificationRecord [ ] fetchNotifications ( ) { if ( notifications . isEmpty ( ) ) { final long timedOut = System . nanoTime ( ) + deliveryInterval ; synchronized ( waitFlag ) { while ( notifications . isEmpty ( ) && ( System . nanoTime ( ) < timedOut ) ) { try { waitFlag . wait ( deliveryInterval / 1000000L ) ; } catch ( InterruptedException e ) { } } } } NotificationRecord [ ] fetchedNotifications = null ; if ( ! notifications . isEmpty ( ) ) { synchronized ( notifications ) { fetchedNotifications = notifications . toArray ( new NotificationRecord [ notifications . size ( ) ] ) ; notifications . clear ( ) ; } } lastAccessTimeStamp = System . nanoTime ( ) ; return fetchedNotifications ; }
The client requested to fetch the notification. If the list is not empty, we build the array right away.
If the list is empty, we wait for whichever event comes first: (1) we time out, (2) we receive a notification