Threads should pass messages, not share memory

Highly recommended reading for any of my students out there: a comparison of message-passing concurrency vs. shared-memory concurrency, with a healthy dose of historical perspective. The author introduces Erlang-style concurrency in a Java-ish setting, and does so quite well, to my mind.

Reading the introductory remarks about candidates in interviews, I was pleased, nay, smug to realise that – albeit inadvertantly – I came to multi-threaded programming via the message-passing route, and would probably have made him quite happy if he’d interviewed me. Back when I worked at Frontier I did my first multi-threading work, in Python, and made heavy use of its excellent Queue class for inter-thread communication. Queue provides a thread-safe message passing mechanism, hiding all the nasty details of locking from me, which was exactly what I was looking for. My threads shared almost no state, and what state they did share was mostly Queue objects. They communicated by passing messages through Queues (messages could be anything, and often were), and it was all lovely and clean.

Why did I go down that route? No genius; I just got lucky (yeah, lucky in that I was using Python not Java or C or C++). I had excellent advice from the good folk on comp.lang.python/python-list: this was the way to proceed. Of course, looking back I realise many of these guys knew all about message passing vs shared memory, they knew about Erlang, they knew about Haskell, hell some of them even knew about Lisp. A community as smart and welcoming as that one is a precious resource for a budding programmer.

Anyway, this led to two strongly noticeable results.

First, my code worked well, and didn’t suffer from mysterious hard-to-debug race conditions, etc. It “just worked”, as is often the way with Python.

Second (confession time), I didn’t actually learn properly about semaphores, monitors, shared memory concurrency and all its ridiculous fiddly baggage until I came to teach them in the Operating Systems module at Swansea! By then I’d already formed a strong sense that high-level languages (and Python in particular) made life so much sensibler, so the shared memory stuff slotted quite readily into the mental space of “low level stuff which has to be understood, but is best done by software not humans” (like much of that module).

I was discussing this whole issue with one of my students earlier in the week. If she closed her app’s main window while a worker thread was running, the program would exit uncleanly. This being Python, it was nothing more drastic than an exception/traceback, but she found this properly displeasing and wanted to clean it up (good, I said). It turned out that the main thread wasn’t waiting for the worker to finish: it exited immediately, cleaning up all data, including data the worker was trying to update. Hence, exception city. I showed the simple fix (make the main thread wait for the worker to finish, using a shared boolean “I’m not dead yet” variable), but then I tried to persuade her that message-passing concurrency was the way to go for all inter-thread communication. Even, said I, right down to the (frequent, many) interface updates caused by the worker thread. That is, I suggested, the worker shouldn’t update the GUI component directly, because the GUI is owned by the main thread. Instead, the worker should pass messages to the main thread telling it what updates to perform, and the main thread should poll for these messages and do the updates. I don’t think I sold her on it entirely, but maybe I planted sump’n.

(Caveat: yes, if performance really matters – eg you’re doing volume graphics – this may be poor advice. For the other 95% of us, however…)

Why the iPhone puts Java into the past tense (apparently)

In Which I Think About Java Again, But Only For A Moment [smallcool].

Me, I defected long ago. I’m another of those Apple Java engineers who dropped out. I spent five years as a raving Java fanboy, but I gave up after optimizing AWT, implementing drag and drop, and trying to make 1,200 pages of crappy APIs do the right thing on the Mac. Then I took a one-week Cocoa training course, and wrote the first prototype of iChat.

Desktop Java never worked because Sun tried to build their own OS on top of the real OS, duplicating every API and feature. This led to terrible bloat, making every app as heavyweight to launch as Photoshop. Worse, the GUI portions of the Java platform are awful, because Sun is a server company with no core competency at GUIs. The APIs are too clumsy to code to, and compared to any decent Mac app, the results look like a Soviet tractor built on a Monday.

He almost makes me want to get a Mac, ditch BSD and emacs, and start writing Cocoa apps – except that then life would just be too darn easy, and I’d never hear the end of it from TR (or Bash, probably).

It’s always somewhat depressing, or at least downheartening, to see someone like this tell me I shouldn’t be using emacs. It always makes me wonder if, maybe, they’re right – maybe out there there’s an editor that’ll do everything emacs does for me, but somehow nicer, more productive. Usually, as far as I can tell, that means the editor does IDE-like things such as autocompletion, code browsing, etc. – and yes, that’s stuff I just don’t use when coding. But gosh darn it, I’ve tried a lot of editors and nothing has ever come close, for me, to the feeling of power and (welcome) flexibility emacs gives me. Effortlessly editing multiple files in multiple split views in multiple windows (across multiple virtual desktops), powerful and easy regexp and macro capabilities, and (as one of the commenters on the linked article says) just doing The Right Thing with indentation in Python, Java, C, Haskell, … So the downheartening aspect is the tantalising feeling that there’s something else out there I should be using, but I just can’t find it! Of course, not using a Mac probably doesn’t help me, here. ;-)

I haven’t listened to Depeche Mode for a while, mind…

Oh, and here‘s another “Java is rubbish” story (comparing EJB lines of code with python/django) from the same source.