Don’t lock

If you write a lock statement you’re doing something wrong.

Now that I have your attention, let me qualify that. If you’re writing business applications and there is any explicit data synchronization code (locks, mutexes, semaphores, etc.) in your business logic, you’re doing it wrong.

It occurs to me that my original statement can be interpreted another way. Using locks correctly is very difficult, even for an experienced programmer. The likelihood that you made a mistake in how you use the lock is very high. That’s not the interpretation I originally intended, but it’s another reason not to use locks if you can avoid them.

I know that some of you will disagree with me. That’s okay. Being wrong isn’t a crime. Continuing to do it wrong even after learning how to do it right isn’t a crime either. It’s just stupid. Using locks to control access to mutable data is wrong. It will lead you down a dark and dangerous path, most likely resulting in the complete failure of your program.

One of the most important lessons we’ve learned over the last 50 years of developing computer programs is that we must strictly control how data is changed. Global variables, although convenient, put your data at risk because any bit of code can change them. The same is true of mutable public fields or properties, which are little more than globals dressed up in an object-oriented wrapper. The risk of something setting an incorrect value or modifying a variable at an inopportune time increases with the number of things that have access to that variable. The risk of something failing because the variable changed increases with the square of the number of things that can modify it.

In a computer program working with thousands or millions of objects, the number of possible failures is frighteningly large. That’s one reason we “hide” objects from each other, and why objects hide their internal implementation details: to reduce the risk that something will inadvertently change a critical value. Strictly controlling access to data makes programs easier to write, easier to change, and more reliable.

We learned those lessons in the days of single processor, single core computers, when the vast majority of programs were single threaded and the computer was doing one thing at a time. The operating system had interrupt routines that ran asynchronously, and multi user operating systems obviously had threading capabilities, but almost all user programs operated on a single thread. It took us decades to learn about the evils of sharing data and to develop programming idioms that minimize the risk.

A typical developer machine today has a single processor with four cores and hyper threading. The computer can be doing eight things at once. Individual programs make increasing use of multiple threads, either cooperating together on a single problem (four threads processing a single large list of items) or each thread handling one part of a multi stage process in a pipelined producer/consumer relationship. This is a Good Thing, except that in writing these applications, programmers are forgetting yesterday’s hard-won lessons.

In our old single threaded programs we focused our attention on keeping data private from other objects. That is, object A was not able to view or change the private implementation details of object B. We learned that a smaller surface area (fewer mutable public properties) meant fewer things could go wrong. But with multithreaded programs we have the potential of multiple threads of execution having access to the private implementation details of a single object. Object A still doesn’t have access to object B’s private parts, but code in object B is being executed by several concurrent threads, all of which have unlimited access to object B’s private parts. This is a recipe for disaster.

Introductory books and articles about multithreading make the mistake of introducing locks, semaphores, events, and other synchronization primitives early on. The descriptions and examples focus on using those primitives (especially locks) to control access to mutable data. After reading those introductory chapters, programmers are left with the impression that the way to “do multithreading” is to wrap their variable accesses in synchronization primitives. Nothing can be further from the truth. The only thing you’ll get from “doing multithreading” that way is a headache: a big monster, eye throbbing, head pounding headache that makes you wish for the mild headache you got when the little kid next door was bouncing his basketball off your bedroom wall while you’re trying to take a nap.

If you’ve done any multithreading work, you’re probably familiar with deadlockslivelocksrace conditionslock convoys, and other multithreading hazards. It’s likely that, like most of us, you’ve written your share of those types of bugs. If you’re smart, you’ve decided that mutable data synchronization is a fool’s errand, and you’ve either learned how to do things the right way or you’ve thrown up your hands in disgust at the craziness and gone back to the single threaded world where things make sense more often.

When you start writing locks, you’re forced to think about how your code works rather than what your code does. Writing explicit synchronization in your business logic is like having to write your code in assembly language rather than in C#. It’s possible, but you’ll spend a lot more time on it and the result will be a lot harder to test, debug, and maintain.

How many times have you asked yourself or your coworkers, “Is this code thread safe?” If you have to ask that about your business logic, you’re doing it wrong! If any other code in your business logic were as complicated and fragile as your multithreading code, you’d insist that it be rewritten. You should not make an exception for multithreading code. You can’t afford to.

I’ve found that the most effective way to write multithreading code is to avoid mutable data and use inter-thread communications protocols in much the same way that we use inter-process communications protocols when working with cooperating processes. I’ve developed the rule with which I opened this article:

If you write a lock statement you’re doing something wrong.

Programs containing threads that communicate by explicitly mutating shared state are fragile. Using locks to protect mutable data fields makes your program more complicated and raises other issues. A more complex program means that it’s harder to write, harder to understand, harder to modify, and more likely to contain intermittent deadlocks and race conditions that aren’t revealed until late in the project–often during user acceptance testing. Worse, proving the correctness of such code is incredibly difficult even for very experienced programmers.

The place for locks and such, if any, is in the data structures that your threads use to communicate with each other. In producer/consumer programs, for example, using a concurrent queue structure such as the .NET BlockingCollection completely eliminates the need for explicit locking in most applications. People who are a lot smarter than you, me, and the vast majority of other programmers have spent years developing and testing those data structures so that you and I can concentrate on our business logic rather than on the incredibly complex world of locks, semaphores, etc.

Programs that work with multiple threads are inherently more complex than single threaded programs. But they don’t have to be so monumentally more complex that even very experienced programmers have difficulty doing the simplest things. I’ve found that I can eliminate shared mutable state by using concurrent collections and other inter-thread communications. And when I eliminate the shared mutable state I find there is no need in those programs for explicit synchronization.

I’ll be exploring that idea in future articles.

One example is my two part Simple multithreading article (Part 2).

Missing the point

I had originally planned to continue my Simple Multithreading series, but there are some other things I need to cover before I start talking about using multiple processing threads. So that project will be delayed a bit until I have a bit of time to think things through. But on a related note . . .

I’m not sure why, but it seems that beginners often don’t get the point of asynchronous processing. For example, a common question is how to use WebClient.DownloadFileAsync to download a file in the background. The code that accompanies the question often looks something like this:

    // at class scope
    private ManualResetEvent DownloadDone = new ManualResetEvent(false);

    private void SomeMethod()
    {
        // initialize WebClient instance
        WebClient client = new WebClient();

        // set event handlers
        client.DownLoadFileCompleted += DownloadCompleted;

        // clear completed flag
        DownloadDone.Reset();

        // start the download
        client.DownloadFileAsync("http://whatever", "filename.pdf");

        // wait for the download to complete
        DownloadDone.WaitOne();

        // Do other stuff
    }

    // and the completed handler
    private void DownloadCompleted(object sender, AsyncCompletedEventArgs e)
    {
        // do end-of download stuff
        // then set event to indicate completion
        DownloadDone.Set();
    }

The code works, but using the asynchronous download isn’t doing any good because the main thread is waiting for the download to complete. The programmer could have saved himself some work by simply writing:

    client.DownloadFile("http://whatever", "filename.pdf");
    // Do other stuff

The whole point of starting an asynchronous download is to do something else while the file is being downloaded. At some point in the future, when you need the file that’s being downloaded, you check to see if it’s done. The right way to do it is:


        // start the download
        client.DownloadFileAsync("http://whatever", "filename.pdf");

        // Do other stuff

        // wait for the download to complete
        DownloadDone.WaitOne();

        // Do stuff that depends on the result of the download

There’s no doubt that the ability to download files asynchronously is cool, but don’t go through the effort of setting up an asynchronous download if your program can’t proceed until the download is done.

I find it surprising that beginners make this particular mistake. I also find it surprising that many find it difficult to understand why the first method is wrong. There is a fundamental piece missing somewhere in the way we teach programming (or perhaps in the way that many learn programming) that leaves a blind spot or a fixation on sequential processing. There has to be some way we can correct that. I just don’t yet know what it is.

Debra: 49 and flab to 50 and fab

Today’s post is guest-written by my wife, Debra Mischel.

My health had been going downhill for several years. With a high stress office job that kept me chained to a desk most of the day and no motivation to get up and move, I was packing on weight. The doctor put me on high blood pressure medication in 2009, and by 2012 I was feeling old, fat, and awful.

There is a history of heart disease and type 2 diabetes in my family, both conditions that are primarily triggered by obesity, and I was heading right down that path. At 5’3″ and 160 pounds, I wasn’t “obese” according to the Body Mass Index, but was close. I didn’t look very good, and I felt terrible.

Like many people, I had had a gym membership for several years, but good intentions don’t take you very far. It seems one has to actually go to the gym in order for the membership to do any good. But doing something requires motivation, and the heavier I got the less motivated I became.

I turned 49 on February 22, 2012, and I knew that I didn’t want to feel this bad when my 50th birthday rolled around. I also knew that I couldn’t make the transformation on my own, so I went to the gym and asked for some help. They set me up with a personal trainer, and we got to work. They gave me diet recommendations that I followed (nothing terrible, mostly just portion control and avoiding the really high-fat, high-sugar foods), and a training schedule.

My training schedule consisted of one hour weight training with a trainer three days per week, and an hour or two of cardio (treadmill, stationary bike, stair climber, or classes) twice per week. On weight training days, I would do a 30 minute warmup on the treadmill.

By July of 2012, I had lost more than 30 pounds and was off the blood pressure medication.

I had met my original goal of getting my weight down to 125 pounds and I felt better than I had in years. But by now I was hooked. I still had some excess fat, and I wanted to build some more muscle. So I kept working with my trainer, stayed with the diet, and kept up the schedule. On my 50th birthday, almost exactly a year after I started my exercise program, I did a five hour weight training workout. I weighed 115 pounds, was stronger than I’d ever been, and felt better than at any time since I was in high school.

At that point I decided to enter the Figure competition at the Naturally Fit show in July. In order to compete, I would have to lose all my excess fat, and build a bit more muscle. I stepped up my workouts so that I was working out twice per day four days per week, heavier on the weight training and a little light on the cardio. The other three days were rest days to let my body recover. I also went on a 20-week “contest prep” diet that consisted of approximately 50% protein, 30% carbs, and 20% fat.

Getting up on that stage in front of hundreds of people, wearing the smallest and most expensive bikini I had ever owned was scary. But I did it. I placed third in the Novice category against six other women, all younger than I, and first in the Masters 50 and Over category.

*

It’s about taking control of your life and responsibility for your own health. I spent years making all the excuses: no time, too expensive, too old, too busy, body hurts, too fat. This transformation cost me, on average, about an hour per day for a year, and then about two hours per day for five months. It cost me some TV time during the week and a few hours of couch potato time on the weekends during contest prep to get my meals ready for the next week. I didn’t even miss it!

You can change your life. It takes hard work, sure. But the benefits are well worth the effort.