Assume that threads really do run concurrently

As mentioned above, it isn't merely a useful "programming abstraction" to pretend that threads run simultaneously; you should design as if they really do. That way, when you move to a multicore system, you won't have any nasty surprises (but you can use BMP if you have problems and don't want to modify the code).