The OSGi Alliance Service Platform (http://www.osgi.org/) is a Java-based environment that is multithreaded from the ground up. The OSGi framework consists of libraries and services designed to execute code from various sources. You can also use the Eclipse OSGI runtime as a standalone framework because it is part of the Eclipse Equinox project, the foundation of the Eclipse Rich Client Platform. However, multithreading in OSGi isn't just about improving performance or taking advantage of chip multiprocessorsit's essential to getting something done. To illustrate, in this article I examine issues that can arise when developing applications that must simultaneously manage UI, computation, and network activity, somewhat akin to what iTunes does. In the process, I discuss solutions I developed in terms of a specific class, ThreadManager. The point of ThreadManager isn't necessarily that you should use italthough that would be fine, toobut that it seems a relatively modest amount of reusable code can go a long way toward easing multithreaded programming.
The OSGi unit of composition is a "bundle." Physically, a bundle is a JAR file, but it is not loaded and processed as typical JAR files are. Each bundle is by default isolated from all other bundles; that is, they cannot invoke each other or even share class declarationseven if those declarations are "public." A bundle exports a package it contains via an export declaration in the JAR manifest. Similarly, a bundle declares which packages it requires via an import declaration. OSGi examines these declarations when bundles are loaded to make sure each import is satisfied, exports do not conflict, and so on. This is all managed via a set of delegating classloaders.
Bundles can be started, stopped, loaded, and unloaded all while OSGi is running. This is important for embedded devices that are "always on"rebooting during "Desperate Housewives" to apply the latest patches just won't do. The OSGi framework tracks dependencies between bundlesfor class definitions and servicesto coordinate these operations.
Of course, set-top boxes aren't really always on; they tend to get unceremoniously unplugged when being moved or when extension cords get tripped over. Consequently, the state of an OSGi device is generally persistent. When an OSGi device starts, bundles are restored to their previous state, running or stopped. Operations such as installing a bundle are transactional for this same reason.
OSGi has been carefully defined, as an embedded environment, to run on top of reasonably sized J2ME profiles. However, it can also be applied to full J2SE environments. The OSGi bundle model is even being adopted as the basis for Eclipse plug-in management.
While thinking of OSGi as an operating system for running Java programs is a good place to start, it has an important difference from operating systemsOSGi does not provide a thread of execution to each bundle. Events are delivered to bundles through certain interfaces, but no guarantees are made about which thread event delivery occurs on. Generally, event callbacks are required to finish quickly and should not make calls back into the OSGi framework to avoid possible deadlock. It is common, therefore, for bundles to start one or more threads in order to get work done.