Jump to content

Thread-local storage: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
m →‎Borland C++ Builder: double redirect fixed
Added Java ThreadLocal example
Line 25: Line 25:
==Language specific implementation==
==Language specific implementation==
Apart from relying on programmers to call the appropriate API functions, it is also possible to extend the programming language to support TLS.
Apart from relying on programmers to call the appropriate API functions, it is also possible to extend the programming language to support TLS.

===Java===
In [[Java programming language|Java]] thread local variables are implemented by the {{Javadoc:SE|java/lang|ThreadLocal}} [[Class (computer science)|class]]. A <code>ThreadLocal</code> object maintains a separate instance of the variable for each thread that calls the object's <code>get</code> or <code>set</code> method. The following example (for [[J2SE]] 5.0 or later version of Java) illustrates using a <code>ThreadLocal</code> that holds an <code>Integer</code> object:

ThreadLocal<Integer> local = new ThreadLocal<Integer>();

the preceeding code declares and instantiates the <code>ThreadLocal</code> object <code>'''local'''</code>. The following code gets the value for the currently executing thread. If the value existed, it is increamented and stored, otherwise the value is set to 1.

Integer val = local.get();
if (val == null)
local.set(1);
else
local.set(val + 1);

<code>'''local.get()'''<code> returns the current <code>Integer</code> object associated with the current thread, or [[null]] if no object has been associated with the thread. The code calls <code>'''local.set()'''</code> to set a new (or initial) value associated with the thread. (Note that the above example uses both [[generic programming|generics]] and [[autoboxing]]&mdash;features added to Java in J2SE 5.0.)


===Sun Studio C/C++ & GNU C===
===Sun Studio C/C++ & GNU C===

Revision as of 01:08, 31 January 2006

In computer programming, thread-local storage is static or global memory local to a thread.

This is sometimes needed because all threads in a process share the same address space. In other words, data in a static or global variable is normally always located at the same memory location, when referred to by threads from the same process. Variables on the stack however are local to threads, because each thread has its own stack, residing in a different memory location.

Sometimes it is desirable that two threads referring to the same static or global variable are actually referring to different memory locations, thereby making the variable thread local.

If it is possible to make at least a memory address sized variable thread local, it is in principle possible to make arbitrarily sized memory blocks thread local, by allocating such a memory block and storing the memory address of that block in a thread local variable.

Windows implementation

One can use the API function TlsAlloc to obtain an unused TLS index. The TLS index will then be considered ‘used’.

Using the API function TlsSetValue you can write a memory address to a thread local variable identified by the TLS index.

Afterwards you can use the API function TlsGetValue to read the address from the variable identified by the TLS index.

When you're done with it you can call TlsFree to release the TLS index. Now it will be considered ‘unused’ so a new call to TlsAlloc can return it again.

Pthreads implementation

TLS with Pthreads is similar to TlsAlloc & co. for Windows. pthread_key_create creates a key, with an optional destructor, that can later be associated with thread specific data via pthread_setspecific. The data can be retrieved using pthread_getspecific. If the thread specific value is not NULL, the destructor will be called when the thread exits. Additionally, key must be destroyed with pthread_key_delete.

Language specific implementation

Apart from relying on programmers to call the appropriate API functions, it is also possible to extend the programming language to support TLS.

Java

In Java thread local variables are implemented by the ThreadLocal class. A ThreadLocal object maintains a separate instance of the variable for each thread that calls the object's get or set method. The following example (for J2SE 5.0 or later version of Java) illustrates using a ThreadLocal that holds an Integer object:

ThreadLocal<Integer> local = new ThreadLocal<Integer>();

the preceeding code declares and instantiates the ThreadLocal object local. The following code gets the value for the currently executing thread. If the value existed, it is increamented and stored, otherwise the value is set to 1.

Integer val = local.get();
if (val == null)
    local.set(1);
else
    local.set(val + 1);

local.get() returns the current Integer object associated with the current thread, or null if no object has been associated with the thread. The code calls local.set() to set a new (or initial) value associated with the thread. (Note that the above example uses both generics and autoboxing—features added to Java in J2SE 5.0.)

Sun Studio C/C++ & GNU C

With Sun Studio C/C++ & GNU C, the keyword __thread is used like this:

__thread int number;
  • __thread defines number to be a thread local variable.
  • int defines the type of number to be of type int.

Visual C++

In Visual C++ the keywords declspec(thread) are used like this:

declspec(thread) int number;
  • declspec(thread) defines number to be a thread local variable.
  • int defines the type of number to be of type int.

Borland C++ Builder

In Borland C++ Builder the keywords __declspec(thread) are used like this:

__declspec(thread) int number;

the same in a more elegant way:

int __thread number;
  • __declspec(thread) defines number to be a thread local variable. __thread is a synonym for __declspec(thread).
  • int defines the type of number to be of type int.