Seibel: So Java provides, as you say, building blocks that let you getportable access to threads provided by the OS and then some higher-levelconstructs with the java.util.concurrent API. But they’re still pretty lowlevelconstructs compared to something like Erlang or STM, aren’t they?

Bloch: I’m not so sure. Some of Java’s building blocks are low-level, likeAtomicInteger; some are midlevel, like CyclicBarrier; and some are highlevel,like ConcurrentHashMap and ThreadPoolExecutor. I believe that STMand actors could both find comfortable homes in Java’s “concurrencybuilding blocks” approach when and if people are convinced that they pulltheir weight.

Some form of transactional memory may become important in the future,perhaps as a building block for use by concurrency library designers. But Idon’t think STM will succeed as a tool that lets the application programmerstop worrying about locks and live in a beautiful world where threads don’tinterfere with one another. It’s just not going to happen.

There are a bunch of reasons for this. Here’s one I learned when I workedin transaction systems. When you try to do automatic locking or optimisticconcurrency control based merely on reading and writing at the byte level,you end up with “false contention” between threads: you have physicalconflicts that don’t correspond to logical conflicts. If you’re forced to thinkabout what locks to acquire, you can do your best to ensure that you don’tacquire any locks beyond what is required to enforce logical conflicts.

So, for example, if you have two threads, both of which are incrementing acounter, they should be allowed to proceed concurrently. They may beaccessing the same piece of memory but they’re not conflicting with eachother from a logical perspective. If you have one thread that’s reading acounter and one that’s incrementing it, they’re in conflict. But you can havearbitrarily many readers or arbitrarily many incrementers proceedingconcurrently. This is the sort of thing that no system that I’ve seen to datecan figure out of its own accord. The counter example may be artificial, butit’s not uncommon that physical contention is far more restrictive thanlogical contention.

Another problem with STM is that there are all manner of operations thatcan’t occur inside a transaction. I/O is the classic example. A third problemis that some STM schemes allow “doomed transactions” to view memory ininconsistent states, with potentially disastrous results. Again, these areproblems that we struggled with back when we were building generalpurposedistributed transaction systems. They have solutions, but all thesolutions I know of add complexity or reduce performance.

Anyway, to the best of my knowledge, STM is still research. I think it’s greatthat people are doing this research. But I simply don’t believe in a silverbullet for concurrency, at least for the foreseeable future.

Seibel: OK, different topic: how do you prefer to work with otherprogrammers?

Bloch: I’m actually quite flexible. I love “buddy programming” whereyou’re working with someone else but not at the same keyboard. You’rewriting different parts of the system—you trade the code back and forth.You don’t even have to be in the same hemisphere. Doug Lea and I haveworked that way extensively over the years. One of us will write aninterface and the other one will say, “Well this is great but this part sucksand I changed it this way.”

Eventually we arrive at some interface that we like and I’ll implement thenonconcurrent version and he’ll implement the concurrent version and aswe do that, we’ll find out all the things that we did wrong and take anothercrack at the interface. And we’ll read each other’s code and he’ll say, “Well,you can make this much faster this way,” and I’ll say, “You’re right, Doug,you can.” He’s very good at making things go fast—he kind of communeswith the VM. So that’s one style that I like a lot. And that lends itself toremote collaborations.

I do like sitting at the same terminal with someone and working on code,but I haven’t written many programs that way from the ground up. Typicallyit’s in the context of a code review where I’ll get some code to review andthere’ll be a lot of changes and I’ll say, “Why don’t we just sit together at amachine and bash it into shape?” That’s good for a whole bunch of reasons.I think it’s a great way to teach, to pass knowledge down from onegeneration of hacker to the next.

I don’t like working in total isolation. When I’m writing a program and Icome to a tricky design decision, I just have to bounce it off someone else.At every place I’ve worked, I’ve had one or more colleagues I could bounceideas off of. That’s critically important for me; I need that feedback.

Seibel: Is that for the feedback you get or just for the chance to talk itthrough?

Bloch: Both. There’s so much craft in what we do—it’s often the case thatthere’s no one right solution, or if there is, it’s not apparent until you’veused it. You have to go from the gut and talking to someone with a differentperspective can be very helpful.

I’ve known people who don’t feel this way—who are willing to program in avacuum. I think it hurts them. You will discover your bugs earlier—youreally want to discover problems with a design long before it hits the pointof code. So when you’re wrestling with different approaches or evendifferent features—should I support this and this or simply that—you justhave to bounce it off other people. On the other hand, you can’t take whateach person says as gospel because you’ll get conflicting opinions, andultimately, you are responsible for your own work.

Seibel: That raises another age-old question—I think Weinberg wroteabout this in The Psychology of Computer Programming in the ’70s and theXPers talk about it today: should code be “owned” by one person who isthe only person who ever touches it or should everyone on a projectcollectively own all the code so anyone can fiddle with anything?

Bloch: I believe that code ownership can’t be denied. In a way, it’s likemotherhood—you give birth to the code that you write, and especially if it’slarge, complex, or original, it is yours. If you find yourself working insomeone else’s code, talk to them before mucking with their code.Especially if you think there’s something really wrong with it, because youmight be wrong. If you break someone else’s code, that’s not nice.

Of course, it’s bad for an organization if a piece of code belongs to exactlyone person because if that person leaves the organization, they’re high anddry. So it’s really important that multiple people learn about each piece ofcode and are able to work on it. But I think it’s unrealistic to expecteveryone to own all the code.

This also touches on what we were discussing earlier in terms of areas ofexpertise. There aren’t that many people who can really write bit-twiddlingcode, so if you find yourself in the bowels of some code that’s doing bittwiddling, you should talk to one of the few people at your company whocan actually handle that stuff, if you’re not one of them. People who do thisstuff love it and are willing to spend whole days reducing an instructionsequence by one instruction or proving some identity that speeds up acomputation. But it’s so easy to break something. And it’s so easy to writesomething that, let’s say, works well for 232 minus 1 of the 232 possibleinputs. A unit test may or may not test that one value where your newsolution doesn’t work. And if it doesn’t and you broke it, you’re the goat.

Seibel: Speaking of writing intricate code, I’ve noticed that people who aretoo smart, in a certain dimension anyway, make the worst code. Becausethey can actually fit the whole thing in their head they can write these greatreams of spaghetti code.


Перейти на страницу:
Изменить размер шрифта: