Wednesday, April 24, 2013

ThreadLocal

ThreadLocal example on Oracle documentation does not work, I tried to report it but the steps involved are so cumbersome, I have chosen to post the solution here.

Here is the code that works as intended (ignore the wrong indentation).


import java.util.concurrent.atomic.AtomicInteger;


public class Threads implements Runnable {
    private static final AtomicInteger numThreads = new AtomicInteger(0);

    private static final ThreadLocal < Integer > threadIdHolder
        new ThreadLocal < Integer > ();

    public int getCurrentThreadId() {
        return threadIdHolder.get();
    }

    public Threads() {
    threadIdHolder.set(numThreads.getAndIncrement());
    }
@Override
public void run() {
System.out.println(getCurrentThreadId());
}

private static Integer getNumberOfThreads() {
return numThreads.get();
}

public static void main(String[] args) {
for (int i=0; i<4 i="" p="">
(new Thread(new Threads())).run();
}
System.out.println("Number of threads is: "+getNumberOfThreads());
}
}

The trouble with the code posted in Oracle documentation (http://docs.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html) is that it tries to use the initialValue() method to increment the numThreads variable. However it is called only once because it is static. It can be fixed by making it non static. Alternately keep it static and assign the value to threadIdHolder in the constructor like in this code.

Here is the output:
0
1
2
3
Number of threads is: 4

Friday, January 18, 2013

No job jar file set. User classes may not be found. See JobConf(Class) or JobConf#setJar(String)

 No job jar file set.  User classes may not be found. See JobConf(Class) or JobConf#setJar(String)

This happened when the class was set (which was the popular fix suggested).

In my case extracting the external jars into the jar when exporting the jar helped.