Thread Local Variables


  1. THIS PAGE IS OUT OF DATE: thread-locals are implemented in Jython 2.5.

  2. This page has been left in place for historical purposes relating to Jython 2.2.

Thread-local variables are a concept that was intoduced into cpython at version 2.4. I will not describe them here. Instead I refer you to the cpython documentation for the threading module.

Thread-locals have not yet been introduced to jython, since it is currently at version 2.2. However, until they are "officially" implemented, there is a simple workaround to get thread-local variables in jython 2.2.

Cpython implementation

Cpython comes with two different implementations of thread-local variables

  1. A fast C implementation which is used on platforms where native thread-locals are supported.
  2. A slower pure-python implementation which is used as a fallback when a native implementation is not available.

As you may have guessed, the solution for jython is to use the pure-python fallback implementation. This implementation lives in the cpython Lib/ module.

How to use the cpython implementation on jython

To use the cpython implementation on jython, simply copy the Lib/ module to your jython Lib directory.

Before going any further, there is a simple code change you must make. The reason for making this change is that the pure-python implementation stores information in the instance dictionary of the localbase class. The key under which it is stored is a tuple, which is not legal in jython, whose __dict__ keys must be strings.

Make the following change to the definition of the localbase class, and it will work on jython.

class _localbase(object):
    __slots__ = '_local__key', '_local__args', '_local__lock'

    def __new__(cls, *args, **kw):
        self = object.__new__(cls)
        # Comment out the following line
#        key = '_local__key', 'thread.local.' + str(id(self))
        # Replace it with this line
        key = '_local__key' + 'thread.local.' + str(id(self))
        object.__setattr__(self, '_local__key', key)
        object.__setattr__(self, '_local__args', (args, kw))
        object.__setattr__(self, '_local__lock', RLock())

Importing the definition of threading.local

Normally on cpython, you would import thread-local support like this

from threading import local

On jython, using the above workaround, you could import it like this (assuming you've copied the module to your Lib directory.

    from threading import local
except ImportError:
    from _threading_local import local

Or maybe like this

import threading
if not hasattr(threading, 'local'):
    import _threading_local
    threading.local = _threading_local.local

And that should be all you need to do.

Performance considerations

Since java does have support for thread-local variables (see java.lang.ThreadLocal), it is likely that thread-local variables will be natively implemented on jython fairly soon.

However, until that is the case, the above solution will be fully functional, if slightly slower. When a native implementation becomes available, no code-changes will be necessary, unless perhaps to tidy up the imports.