With the word thread in Java we indicates two things:
- an instance of a
java.lang.Thread, so basically an object living in memory heap;
- a thread of execution, a process with its own stack in memory. In Java one thread has one callstack;
There two types of thread: a user and a demon thread. JVM exits from executon only when every user thread has finished. It doesn’t consider demon threads status.
You can create a Thread extending the class
Thread or implementing the interface
Runnable. The method to override in both cases is
public void run(). It’s legal to overload
run() but only
public void run() is considered when it comes to create a new thread of execution.
To instantiate a thread we have four constructors:
Thread(Runnable target, String name);
It’s possible to pass the same instance of
Runnable to several thread without problem (well, beware of shared data!). When a
Thread has been create it is in the state new, when you call
start(), the state is runnable and a new thread of excution is created but the execution doesn’t start. The thread scheduler decides when a thread has to start the excution, you cannot control it (you can use priorities though).
Be aware that:
It’s legal to call directly the method
run()as long as it’s clear that you are not creating a new thread of excution. That’s possible only when you call
To set a name of a Thread you can use
setName(). If you are using a
Runnable, you can access the name from
Thread.currentThread.getName(), if you have no way to access to the instance of the thread. The name of the thread associated to the method main`, is “main” (duh!).
When you excute more then one thread, you can assure that every thread will be executed, but you can’t say anything about the order of execution of each thread. When the thread has finished the execution of
run(), the thread will be in the state dead.
States of a Thread
- NEW: instance of Thread created(),
start()has not been called yet;
start()has been called and we have a thread of execution, the thread is not running yet;
run()has been executed;
- WAITING/BLOCKED/SLEEPING: the thread is alive but it’s not possible to run it, like because is blocked for an I/O operation;
- DEAD: the method run has finished;
sleep()it’s static and accepts the number of milliseconds. It does not release acquired locks. Launches a
yield()it’s static and launches an
InterruptedException. It tells to the current thread to go back to the state runnable to leave space to other threads but remember that the scheduler decides what to do;
join()it’s an instance method, when called tells to the current thread to wait for the thread who called the
join()to end. It launches an
Be aware that:
When the method
run()finishes the thread sends a
notifyAll()so that if some other thread was waiting on that very same thread, it will wake up.
In many cases the thread in state running will be the one that has higher priority or equal to the thread with the higher priority in runnable state.
A thread has initially the same priority of the current thread where it gets instantiated, but you can set it directly with
In Java the default priority is 5. You also have
- it’s possible to syncronize only methods or code blocks;
- every object and every class have an intrinsic lock;
- a class can have both synchronized and not syncronized methods;
sleepdoes not release locks;
- if a thread has already acquired a lock, you use other syncronized methods using that lock;
Method of the Object class
notifyAll() are instance methods of the class
Object and they are called only in a syncronized context otherwise you’ll get a runtime exception.
wait() releases acquired locks.