use lock to prevent data races