Whatever works for you, but changing 20 lines of code in this to use asyncio will send your throughput through the roof.
Use asyncio (or roll your own toolkit, or just spawn 'nmap') and you get 20000 concurrent connections.
Which is better?
Your 20000 concurrent connections with asyncio are not parallel. You can have 20000 threads if you want.
As you well know 20000 threads is not a great way to do anything. Especially in Python.