I’d like to start easy and say that threading is really hard. It adds a dimension to a program that is just hard to keep in mind all the time. For that is exactly what you have to do, keep it in the back of your head, no mater how small the code change is. Threads are like people travelling on subways. The subways are the shared memory that we all want to use. During rush hours thousands of deadlocks occur from people blocking each other when trying to get on and off. Now, most humans have a built in deadlock preventions system that will help us move around so that most of us get to the point we want. The epiphany of another person is usually enough for someone to stop and let that person through, and then start walking again. In an application it is your job to create such a system.
One of the best solutions to the subway problem would be to remove all other people and just let me go with it. Not really fair, but still an interesting thought. Even more so when it comes to programming. If you are a thread, wouldn’t it be great if you were the only one who got to add and remove objects in the list? That is at least the mindset I believe you should strive for. If a resource is only ever read or written by a single thread then there are no threading issues. I’ve seen threads created because it would be great if a task could be performed in parallel with some other task. It added complexity and obscured the code. The class was scattered with state flags so that it would know what tasks had failed and which had not. The strange thing about it was that if taskA failed then taskB should not be started, it was even so that none of the tasks should start if one failed. Making it in reality parallel, but made asynchronous to increase performance. I removed the threads, the tasks, made it into a sequence of steps. No locks, no state flags, no threads, no complexity. The performance boost from using threads was not needed. I’m critical when it comes to threads, both in legacy code and in new. That said, the feeling when screaming “It’s alive” is so much better with working multithreaded applications.
Threads are usually not as error prone in applications where they were a natural part of the original design. Or in applications that handle thousands of calls at the same time, each in one thread. This I believe is because if you know that you are dealing with threads from the beginning you take actions to prevent the pitfalls you might otherwise end up in. I believe that threading introduced in applications that are a couple of years old is where the real danger resides. This is where the architecture and foundation of the application was not made to be thread safe. A thread might be introduced in a new feature or even a bug report.
As I mentioned in my previous post I collect post-IT notes with the names of the classes that have a thread. For each of these I look for the patterns I describe below.
Is any resource read by this thread also read by another thread?
Then that resource must be made thread safe if it is not so already. There are a number of ways to do this in good fashion. It depends on what the class holds. If the resource is a collection of some sort then creating a thread safe collection from Collections.synchronizedXXX might do the trick. It only works if the class that holds the list does not fetch elements and manipulate them in some method. If that is the case then the class must be made safe by using the Monitor Pattern which in Java is basically making all methods synchronized over a guard variable.
Are there cases where one class that is read by more than one thread have more than one resource?
Why is this so hard? Well, to begin with if a class have two resources they are most likely connected in some way. For instance you might have one Hashmap from Person -> Phone number and then one from Phone number -> Person. If a person is added or removed then both have to be updated. You thus have the option of locking over both of them which will be quite ineffective or having one ReadWriteLock for each of them. That however will mess up your code badly but is sometimes needed. This however is a pattern I have learned to look out for. When I have a class that needs to be thread safe and it has more than one resource, the fact is that the class may violate the Single Responsibility pattern. I break up the class into three classes. One gets to be a facade that mediates the two other classes to the surrounding environment. Making it a mediator for the services of the composing classes. The two classes now have one resource each and thus the synchronization is easier and less complex.
Look for threads involved in the observer pattern
Say that class A wants cars and class B makes cars on demand, both are threads. Class A ask for a BMW but since B is out having sauerkraut things will take a while. B finally makes the order and tells A, who has put it self as a client (observer) on B, that it is ready. Now what’s the problem with this? There is a big one. When B iterates over the list of observers it runs a method on A called carIsReady(new BMW()). The carIsReady method, filled with joy, runs along and adds the car to A:s list of created cars. This will probably work nine out of ten times. But there is a big risk. The carIsReady method is called by B and thus the thread in B. When it runs carIsReady it modifies A:s list, the same list as the thread in A might want to remove cars from. One out of ten times a ConcurrentModificationException will be thrown and the root cause is hidden quite well. This is probably on of the most common pitfalls people find them self in when they introduce threading, it is so easy to forget that just because the code in carIsReady is in class A it doesn’t mean that thread A is executing that code. This is the added dimension that I always have to have in mind. To resolve this I use a BlockingDequeue or BlockingQueue as introduced in Java 5. They are excellent to get rid of this issue.
Is a thread doing too much?
Threads are usually workers, and they do work hard. Sometimes too hard. Take for example a class called FireWall. It has a list of incoming messages and a list of outgoing messages. In the thread loop it first checks the list of incoming messages and then outgoing. It has to filter both for attacks. Once again a violation of the Single Responsibility Pattern. The FireWall is doing to much and should be split in three classes. One class, still named FireWall creates the other two classes: InternalFireWall and ExternalFirewall. Instead of keeping the thread in FireWall I move that logic into each of the new classes. One thread in each of the new classes. Yes, that is right, I just added a thread! What!? Well, the work of sending and receiving is independent and the division into two working classes and one mediator class is a much cleaner and testable design. With this there is however an added complexity of one more thread running around in the system. I only do this when I know that the threads are enclosed and never leave their class. This example is a real one, just other names but the sender and receiver used their own connection using a socket and their threads never did anything except listen or send.
There are many more patterns to look out for when making an application thread safe. These are some of the more common ones that I have experienced. A book that every Java and C# programmer should read is the book “Java - Concurrency in Practice” by Brian Goetz. Reading this will give even the experienced developer some aha-moments.
--Fredrik Bäckström

