When using threads I sometimes visualise them as weaving together 3 or more dimensional interconnections between Objects in a Spatial context. This isn't a general use case scenario, but for what I do it is a useful way to think about it.
Are there any APIs which you use which aid threading?
You mean appart from java.util.concurrent
? FunctionalJava got some constructs which aid in concurrent programming, as described in a multipart tutorial that starts here.
Have you used threads in a manner which doesn't conceptualise as thread being a process?
Yes, to the extent that threads doesn't conceptualise at all. Take an asynchronous task-runner for instance. It uses threads under the covers but I don't see them and I don't care about them. They are fully managed by the task-runner.
Under the covers, it is all just threads, but when we stop caring about the individual thread and just think about them as a number of slots where you can somehow put code in and have it run for a period of time, then that is when we start to reach for a higher level of abstraction.
Agents/Actors is a common way to do this. An Actor is like a thread that has a lump of state, and then you can send it some code and say "do this to your state when you have time" or something along those lines.
Concurrency is a deep and complicated topic to cover. Books like Java Concurrency in Practice may help.
See Concurrency Utilities Overview for APIs on threading. BlockingQueue<E> can be useful for example.
A Queue that additionally supports operations that wait for the queue to become non-empty when retrieving an element, and wait for space to become available in the queue when storing an element.
See CountDownLatch
A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
and CyclicBarrier for some interesting behavior.
A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.
Edit: I am reading Java Concurrency in Practice now. It's very good.
First of all
The usual disclaimer: concurrent programming, in any language, using any abstraction level, is hard and complicated and has many risks. Take into consideration:
- Concurrent programming complicates any application by magnitude
- Unit-testing critical sections is hard, and sometimes impossible
- Reproducing bugs originating in concurrent code is very hard and much dependent on architecture, OS flavor, version, etc...
Java Concurrent APIs
Java has gone a long way in making concurrent programming as easy as possible for developers. For most cases, you will see that java.util.concurrent
has most of the abstractions you will need:
Runnable
interface andThread
object you can extend. Just throw in your code and you have a thread ready to run- A nice set of
Executors
: constant pool, dynamic pool, scheduled, or whatever. Just throw aRunnable
at it and it does the rest. Semaphore
s and locks of all sorts relieve you of needing to implement common locking techniques.- A built-in
wait()
andnotify()
API for all objects.
Uses
The only thing left for you, as the software engineer, is to ensure you are writing correct code. Meaning you should be aware of the dangerous situations you might be exposing yourself to:
- Deadlock - a situation in which two or more threads are waiting on unordered resources, rendering an infinite waiting loop.
- Livelock - two or more threads which politely try to give way to the other on a shared resource but end up not taking it (consider two people in a corridor walking up to each other and constantly moving together from side to side)
- Starvation - a single thread taking up most or all of a single shared resource, thus depriving other threads from access to it.
Main Point (or, when to use)
Use threads only when concurrency will directly improve your applications behavior.
If you are waiting on an IO/network/hardware-bound resource, DO spawn a thread on it so you can continue doing other stuff.
If you are just trying to elegantly split CPU-bound computations, DO NOT use threads. You just might end up worsening your performance.
If you do use threads, make sure you have thoroughly contemplated the risks, and triple-checked you did not miss any exceptional situations.
Useful (Online) Resources
Fastest way to get into things is to do the Sun concurrency tutorial. Other than that, get a good book.
Good luck :)
When using threads I sometimes visualise them as weaving together 3 or more dimensional interconnections between Objects in a Spatial context.
That does sound complicated, how would you conceptualise 600 threads for example? Why not think of them as multiple threads of execution running apparently concurrently.
Are there any APIs which you use which aid threading?
I suggest the simplest and most straight forward are the first matches you would find. http://www.google.co.uk/search?q=java+threads
Have you used threads in a manner which doesn't conceptualise as thread being a process?
Since threads are not processes, I can't say I have ever thought of threads as processes. (Except on old versions of Linux) Processes don't share memory/objects by default for a start, they run completely independently (usually different programs, possibly written in different languages) They are also start differently using different APIs.
There is a view that multi-threading is complicated. Actually I would say the opposite. Multi-threaded programming requires you to make your code simple, easy to understood and straight forward to reason about. While this takes experience, your aim is simplicity.