How do you know when to make it multi-threaded?

I have been learning Java for a while, just started learning GUI development with swing, and through researching this I was introduced to and got interested in multi-threading. My question is how do you know when to make your application multi-threaded, and what type of things are done in a multi-threaded application?

I have a lttile experience in this area (and I mean little so take wiht grain of salt).

There are some very good explanations of the different techniques and strategies for threading in this article. (http://www.drdobbs.com/parallel/the-pillars-of-concurrency/200001985?pgno=1)

There are two main reasons to go multithreaded. The first is responsiveness and the second is pure performance.

Using threads to improve responsiveness allows the GUI (prime example) to keep running smoothly while heavy or slow backgorund work (large tasks or slow network calls) runs on a separate thread. What used to happen in the single threaded days was that background work would cause the GUI to temporaily freeze (you know the "Not Responding" you can see in the top bar of an application) while waiting for the background task to finish. This type of threading is quite simply and creates little issues when developing so you should always really use threads in this manner. The second type is not so simple and should be done with caution!

The second major resaon is simply when single threaded performance isn't enough, you need to start using multiple threads. Now you may ask, why not make all applications multithreaded? The simple reason why not is basically, muiltithreading is difficult. You need to be able to structure you algorithms in ways that take advantage of independent streams of work. This isn't a straight forward process and it really depends on the natural structure of the application you're creating. Sometimes there isn't a lot of inherent parallelism in the task your trying to acomplish. If your application has a lot of dependencies on global values, multiple threads can actually slow down the overall speed if these threads require write access to this value. At this point you need to start introducing locks which are slow and can serialize your nice parallel the applicaiton.

There are tons of issues with threading and a general rule is start with a serial application. If you need more performance try optimizing your code. If that still isn't good enough, then start looking at threads. This is probably an old way of looking at things but multithreading programs can get extrmely complicated extremely quickly; introduciong bugs you may never find (because testing also creates its own issues) and producing perofrmance that can actually be slower than a single threaded versions (issues such as cache coherency can require accessive cache write backs).

Of course this is simplified answer and there are many different techniques and tools that have varying results (again depending on the application). Locks are generally the last tool you want to use (they are inefficient) and advances in alternative tools such as transactional memory and lock free techniques are making improvements. These are not applicable in all areas though and so you may need to fall back on traditional locks.

Thank you for such a detailed answer. So I am guessing a 'lock' makes something only available to one thread at a time so you dont get weird runtime errors? Is this what the synchronized keyword in Java does?

Exactly.

There are many different types of locks too (and each have their own characteristics). Look up spin locks (they spin the locked thread which waste CPU cycles but are cheap) and semaphores (no wasting of CPU cycles but take time to suspend (block) and resume threads). Monitors are another lock similar in characteristics to semaphores but more modern.

I am still not sure how the Java sychronized lock is implemented. Each implemention (in the respective languages) are different and genearlly unkown to public. It most likely uses a monitor but there are adaptive monitors that try to bridge the gap between spin locks and blocking locks.

Thanks man, I just wanted to stop myself and get some input before I went thread crazy. Whenever I learn about something new I always overuse it in my next project. I kind of figured there are good and bad times to use multithreading, just like any tool.

1 Like

I'd like to hear different responses from others to see what they have to say on the subject. I studied quite a bit of the theory but never delved into creating threaded applications.

Actually I'd love to hear what @wendell has to say on the subject.

huge topic.
take a look at haskell - https://donsbot.wordpress.com/2010/06/01/open-source-bridge-talk-multicore-haskell-now/

Some languages are easier than others to go extreme multithread.

1 Like

Functional languages seem to be a whole other ball game when it comes concurrency/parallelism. Advocates of functional languages imply how easy parallel execution can be achieved through explicit operations.

I had found this open source example which show how efficient a haskell implementaiton of image edge detection can be.


(http://disciple-devel.blogspot.ie/2011/03/real-time-edge-detection-in-haskell.html)

All issues such load balancing (and thats a big one) are automatically handled by the repa library.

There are many critics of functional languages although I haven't really looked into functional languages that much. It was a bit out of my scope. Really interesting all the same.