Concurrency Fundamentals in Java
Concurrency Fundamentals
- A multithreaded program contains two or more parts that can run concurrently.
- Multithreading allows tasks waiting for other resources to give way to other processing requests.
- A thread is the smallest unit of execution that the operating system can schedule.
- A process is a group of associated threads executed in the same shared environment.
- A single-threaded process contains exactly one thread, whereas a multithreaded process supports more than one thread.
- In a shared environment, threads in the same process share the same memory space and can communicate directly with one another.
- Concurrency is the property of executing multiple threads and processes simultaneously.
- Operating systems use a thread scheduler to determine which threads should be currently executing.
- A context switch occurs when a thread’s allotted time is complete but the thread has not finished processing.
- A context switch is the process of storing a thread’s current state and later restoring the state of the thread to continue execution.
- When a Java application starts, its
main()method is executed by the main thread – a special thread that is created by the Java VM to run the application. - It is also possible to create and start more threads that can manage parts of the application code in parallel with the main thread.
- A thread can be created in two ways:
- Extend the
Threadclass and override therun()method. - Implement the
Runnableinterface.
- Extend the
Extending the Thread Class
Example:
public class ThreadDemo extends Thread { public static void main(String[] args) { ThreadDemo thread = new ThreadDemo(); thread.start(); System.out.println("Outside of a thread"); } public void run(){ System.out.println("Running in a thread"); } }Output:
Outside of a thread Running in a threadTo start the Java thread, call its
start()method.The
run()method is what is executed by the thread after callingstart().The
start()call will not wait until therun()method is done.The
run()method will execute as if executed by a different CPU.
Implementing the Runnable Interface
Example:
public class ThreadDemo implements Runnable { public static void main(String[] args) { ThreadDemo obj = new ThreadDemo(); Thread thread = new Thread(obj); thread.start(); System.out.println("Outside of a thread"); } public void run(){ System.out.println("Running in a thread"); } }A thread can be run by passing an instance of the class to a
Threadobject's constructor and then calling the thread'sstart()method.
Thread Methods
The Thread class consists of several methods that allow you to manage threads:
| Method | Description |
|---|---|
start() | Starts a thread by calling its run method |
run() | The entry point for the thread |
setName() | Sets a thread’s name |
getName() | Obtains a thread’s name |
setPriority() | Sets a thread’s priority |
getPriority() | Obtains a thread’s priority |
isAlive() | Determines if a thread is still running |
join() | Waits for a thread to terminate |
sleep() | Suspends a thread for a period of time |
- A thread can interrupt or supersede another thread with a higher thread priority than the other thread.
- A thread priority is a numeric value associated with a thread that is taken into consideration by the thread scheduler when determining which threads should currently be executing.
- The value of the priority level must be within the range
MIN_PRIORITYandMAX_PRIORITY. - These values are 1 and 10, respectively.
- To return a thread to default priority, specify
NORM_PRIORITY, which is 5.
Thread Methods Examples
The following sample program shows the use of
setName(),getName(), andsetPriority().public class ThreadDemo extends Thread { public static void main(String[] args) { ThreadDemo t1 = new ThreadDemo(); ThreadDemo t2 = new ThreadDemo(); ThreadDemo t3 = new ThreadDemo();
}t1.setName("One"); t2.setName("Two"); t3.setName("Three"); t1.setPriority(4); t2.setPriority(Thread.MAX_PRIORITY); t3.setPriority(8); t1.start(); t2.start(); t3.start(); } public void run(){ System.out.println(Thread.currentThread().getName() + " is running."); }Output:
Two is running. Three is running. One is running.The
Thread.currentThread()method returns a reference to theThreadinstance executingcurrentThread().This way, the Java Thread object representing the thread executing a given block of code can be accessed.
A thread with higher priority does not necessarily mean that it will run faster or more often than others; it only has greater potential access to the CPU.
The following sample program shows the use of
sleep(),join(), andisAlive().public class ThreadDemo extends Thread { public static void main(String[] args) { ThreadDemo t1 = new ThreadDemo(); ThreadDemo t2 = new ThreadDemo();
}t1.start(); //starts 2nd thread after 2 sec or if it is dead try { t1.join(2000); } catch(InterruptedException e) { e.printStackTrace(); } t2.start(); //waits for the threads to terminate try { t1.join(); t2.join(); } catch(InterruptedException e) { e.printStackTrace(); } System.out.println("Thread-0 is alive: " + t1.isAlive()); System.out.println("Thread-1 is alive: " + t2.isAlive()); } public void run(){ System.out.println(Thread.currentThread().getName() + " is running."); try { Thread.sleep(3000); //suspends thread for 3 seconds } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " has ended."); }Output:
Thread-0 is running. Thread-1 is running. Thread-0 has ended. Thread-1 has ended. Thread-0 is alive: false Thread-1 is alive: false