I've used threads in C and Java. In C, I used the pthreads (POSIX threads) library. Of course, it's not as peaceful as threads in Java.
Synchronization is done using mutexes and condition variables. Mutexes allow you to avoid race conditions. Condition variables allow you to wait until any specified condition is satisfied. There's a bunch of functions that are used to do this - pthread_mutex_init/lock/unlock/trylock etc. and pthread_cond_init/wait/broadcast etc.
Of course, thread operations are completely procedural in nature - pthread library functions that take as arguments function pointers/thread variables (pthread_t) and such other stuff.
Here's a decent tutorial for pthreads.
Sometimes, it's better to just fork() processes and have them communicate using pipes, semaphores in shared memory etc.
Just a personal opinion - while a lot of things are much easier to do in Java, I would still recommend trying them out in C (or C++) atleast once. You just get a slightly 'inside' view of things... not just threads, even stuff like socket programming. However, for day to day use, Java's a better bet.
Have never used threads in Lisp but I do know that there's a package for threads. While Lisp is projected as an AI language, it has support for a whole lot of things from threads, sockets, interfacing with the OS etc. (OT - While the 'biggest deal' about lisp is its natural use to do functional programming, it also supports procedural and object oriented programming)