- Java Concurrency / Multithreading Tutorial
- Multithreading Benefits
- Multithreading Costs
- Concurrency Models
- Same-threading
- Concurrency vs. Parallelism
- Creating and Starting Java Threads
- Race Conditions and Critical Sections
- Thread Safety and Shared Resources
- Thread Safety and Immutability
- Java Memory Model
- Java Synchronized Blocks
- Java Volatile Keyword
- Java ThreadLocal
- Thread Signaling
- Deadlock
- Deadlock Prevention
- Starvation and Fairness
- Nested Monitor Lockout
- Slipped Conditions
- Locks in Java
- Read / Write Locks in Java
- Reentrance Lockout
- Semaphores
- Blocking Queues
- Thread Pools
- Compare and Swap
- Anatomy of a Synchronizer
- Non-blocking Algorithms
- Amdahl's Law
- Java Concurrency References
Creating and Starting Java Threads
Jakob Jenkov |
Java threads are objects like any other Java objects.
Threads are instances of class java.lang.Thread, or
instances of subclasses of this class. In addition to
being objects, java threads can also execute code.
Java Threads Video Tutorial
Here is a video version of this Java threads tutorial.
Creating and Starting Threads
Creating a thread in Java is done like this:
Thread thread = new Thread();
To start the Java thread you will call its start() method, like this:
thread.start();
This example doesn't specify any code for the thread to execute. The thread will stop again right away after it is started.
There are two ways to specify what code the thread should execute. The
first is to create a subclass of Thread and override the run() method.
The second method is to pass an object that implements Runnable
(java.lang.Runnable to the
Thread constructor. Both methods are covered below.
Thread Subclass
The first way to specify what code a thread is to run,
is to create a subclass of Thread and override the run() method.
The run() method is what is executed by the thread after you call start().
Here is an example of creating a Java Thread subclass:
public class MyThread extends Thread {
public void run(){
System.out.println("MyThread running");
}
}
To create and start the above thread you can do like this:
MyThread myThread = new MyThread(); myTread.start();
The start() call will return as soon as the thread is started. It will
not wait until the run() method is done. The run() method will execute
as if executed by a different CPU. When the run() method executes it
will print out the text "MyThread running".
You can also create an anonymous subclass of Thread like this:
Thread thread = new Thread(){
public void run(){
System.out.println("Thread Running");
}
}
thread.start();
This example will print out the text "Thread running" once the run() method
is executed by the new thread.
Runnable Interface Implementation
The second way to specify what code a thread should run is by creating a class
that implements java.lang.Runnable. The Runnable object can be executed by
a Thread.
Here is a Java Runnable example:
public class MyRunnable implements Runnable {
public void run(){
System.out.println("MyRunnable running");
}
}
To have the run() method executed by a thread, pass an instance of MyRunnable
to a Thread in its constructor. Here is how that is done:
Thread thread = new Thread(new MyRunnable()); thread.start();
When the thread is started it will call the run() method of the MyRunnable
instance instead of executing it's own run() method. The above example
would print out the text "MyRunnable running".
You can also create an anonymous implementation of Runnable, like this:
Runnable myRunnable = new Runnable(){
public void run(){
System.out.println("Runnable running");
}
}
Thread thread = new Thread(myRunnable);
thread.start();
Subclass or Runnable?
There are no rules about which of the two methods that is the best. Both methods
works. Personally though, I prefer implementing Runnable, and
handing an instance of the implementation to a Thread instance. When having
the Runnable's executed by a thread pool it is easy to queue up the Runnable
instances until a thread from the pool is idle. This is a little harder to
do with Thread subclasses.
Sometimes you may have to implement Runnable as well as subclass Thread.
For instance, if creating a subclass of Thread that can
execute more than one Runnable. This is typically the case when implementing
a thread pool.
Common Pitfall: Calling run() Instead of start()
When creating and starting a thread a common mistake is to call the run() method
of the Thread instead of start(), like this:
Thread newThread = new Thread(MyRunnable()); newThread.run(); //should be start();
At first you may not notice anything because the Runnable's run() method is executed
like you expected. However, it is NOT executed by the new thread you just created.
Instead the run() method is executed by the thread that created the thread. In
other words, the thread that executed the above two lines of code. To have the
run() method of the MyRunnable instance called by the new created thread, newThread,
you MUST call the newThread.start() method.
Thread Names
When you create a Java thread you can give it a name. The name can help you distinguish
different threads from each other. For instance, if multiple threads write to
System.out it can be handy to see which thread wrote the text. Here is an example:
Thread thread = new Thread("New Thread") {
public void run(){
System.out.println("run by: " + getName());
}
};
thread.start();
System.out.println(thread.getName());
Notice the string "New Thread" passed as parameter to the
Thread constructor. This string is the name of the thread. The name
can be obtained via the Thread's getName() method. You can also
pass a name to a Thread when using a Runnable implementation. Here
is how that looks:
MyRunnable runnable = new MyRunnable(); Thread thread = new Thread(runnable, "New Thread"); thread.start(); System.out.println(thread.getName());
Notice however, that since the MyRunnable class is not a subclass of
Thread, it does not have access to the getName() method of the thread
executing it.
Thread.currentThread()
The Thread.currentThread() method returns a reference to the Thread instance executing
currentThread() . This way you can get access to the Java Thread object representing
the thread executing a given block of code. Here is an example of how to use Thread.currentThread() :
Thread thread = Thread.currentThread();
Once you have a reference to the Thread object, you can call methods on it. For instance, you can get
the name of the thread currently executing the code like this:
String threadName = Thread.currentThread().getName();
Java Thread Example
Here is a small example. First it prints out the name of the
thread executing the main() method. This thread is assigned by the
JVM. Then it starts up 10 threads and give them all a number as
name ("" + i). Each thread then prints its name out, and then stops
executing.
public class ThreadExample {
public static void main(String[] args){
System.out.println(Thread.currentThread().getName());
for(int i=0; i<10; i++){
new Thread("" + i){
public void run(){
System.out.println("Thread: " + getName() + " running");
}
}.start();
}
}
}
Note that even if the threads are started in sequence (1, 2, 3 etc.) they may not
execute sequentially, meaning thread 1 may not be the first thread to write its
name to System.out. This is because the threads are in principle executing in parallel
and not sequentially.
The JVM and/or operating system determines the order in which the threads are executed.
This order does not have to be the same order in which they were started.
| Tweet | |
Jakob Jenkov | |