add multi-thread support