BasicDataSource is everything for basic needs. It creates internally a PoolableDataSource and an ObjectPool.
PoolableDataSource implements the DataSource interface using a provided ObjectPool. PoolingDataSource take cares of connections and ObjectPool take cares of holding and counting this object.
I would recommend using BasicDataSource. Only, If you really need something special maybe then you can use PoolingDatasource with another implementation of ObjectPool, but it will be very rare and specific.
BasicDataSource is thread-safe, but you should take care to use appropriate accessors rather than accessing protected fields directly to ensure thread-safety.