Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is java.lang.Thread itself a thread-safe class?

I was wondering do we require external synchronization to use the methods in java.lang.Thread?

For example, can we call the method t1.isAlive() from any thread without external synchronization and expect that it return:

true if t1 has already been started, false otherwise.

Or is external synchronization required to call the methods in java.lang.Thread?

public static void main(String args[]) {
        final java.lang.Thread t1 = new java.lang.Thread(new java.lang.Runnable() {

            @Override
            public void run() {
                while(true){
                    //task
                }
            }
        });
        java.lang.Thread t2 = new java.lang.Thread(new java.lang.Runnable() {

            @Override
            public void run() {
                while (true) {
                    System.out.println(t1.isAlive()); // do we need synchronization before calling isAlive() ?
                }
            }
        });
        t2.start();
        t1.start();
        try {
            java.lang.Thread.sleep(1000000);
        } catch (java.lang.InterruptedException e) {
            e.printStackTrace();
        }
    }
like image 541
Pacerier Avatar asked Feb 19 '12 04:02

Pacerier


1 Answers

Yes it should already be thread safe. You can look at the source code of Thread.java here all the important methods such as start etc are synchronized.

The is_Alive is a native method implemented in a lower layer so will give an instantaneous answer as to whether the thread is started or not, it is not synchronized so it may give a false right after the start method is called. Although this is very very rare.

The start method does however check the threadStatus member variable before proceeding with its operation and this is a volatile int i.e. will be instantly updated across all accessing threads. So you can use the getState call to check whether a thread is started rather than the isAlive method to avoid the calling start twice. I have copyied the relevant parts of Thread.java below.

/* Java thread status for tools,
 * initialized to indicate thread 'not yet started'
 */

private volatile int threadStatus = 0;

...

public synchronized void start() {
    /**
     * This method is not invoked for the main method thread or "system"
     * group threads created/set up by the VM. Any new functionality added
     * to this method in the future may have to also be added to the VM.
     *
     * A zero status value corresponds to state "NEW".
     */
    if (threadStatus != 0)
        throw new IllegalThreadStateException();
....

public State getState() {
    // get current thread state
    return sun.misc.VM.toThreadState(threadStatus);
}
like image 154
Usman Ismail Avatar answered Sep 29 '22 15:09

Usman Ismail