Use double check locking for credentials lazy initializing in credential providers

This is to make sure EC2 credential provider does not hit metadata service too many times in a highly concurrent environment.

We have a server runs on EC2 using instance profile for AWS authentication. The server is for background processing and every-time it boots up there are 35 threads start fetching messages from SQS. Thus resulting in about 30 requests hitting EC2 metadata server (169.254.169.254) at same time. Metadata server returns 429 (Too Many Requests) for some threads, and set back an empty credential ({}) as cached value. If broken threads finished first and its result get cached, MissingCredentialsError will be thrown.

This pull request solve the problem by putting a mutex around the caching logic. So if multiple threads come in at same time, the first one will fetch credentials and all the rest wait. Also this is a double check locking, so once credential get cached we do not need pay the cost of synchronize anymore.

-- wpc