All sockets are asynchronous and use a seperate thread because of the basic nature of the I/O. However:
When you want to receive data from a socket, you can simply call a receive data method. However, if the data is not immediately available, then your thread will block. Most socket API's have a timeout exception that will be thrown if you don't receive data within some set time period. At this point, your program can give up or try again, but either way, all this blocking blows. This technique is using sockets synchronously.
Alternatively, you can poll your sockets for data. Actually, a lot of socket libraries will simply call you back when data is available (real async). If there is no data, you just go on with your life. In this case, there is no timeout, because you won't call read unless there is actually data waiting for you. This technique is asynchronous.
By the way, though C and the like had asynchronous socket, if you were programming in Java before 1.3 or something, you ONLY had blocking I/O. I was doing network programming in C++ at the time, so I got to skip out on that whole headache.