I've found a bugreport that is similar to my problem
Did you read the comments there? Especially this one: "You have to create the engine in the same thread as the one where you are using it. And you cannot create your function in one thread and call it in a different one.".
You can't make it thread safe without changing its implementation. Is there a reason why you wantr to use it from different threads?
Yeah, there's need of evaluating JS code and accessing a QJSEngine object from different threads because of my program specificity. However there should be workaround to make it possible, like switching to the engine's thread before accessing to QJSEngine object. All I have found is using signal/slot system or QMetaObject:: invokeMethod (the last one is provided in the bugreport) to do that, but none of them work at the test code, I don't know why.