Shouldn't the synchronization in the run thread only be synchronized around the notification, applying changes, and clearing?  This way the thread can be sleeping in the wait while changes are getting added, and will then be locked only when applying the changes.