Threads allow multiple tasks to run concurrently within a single process. Each thread has its own call stack and shares resources like memory with other threads in the same process. There are two main ways to implement threads in Java - by extending the Thread class or implementing the Runnable interface. Synchronization is needed when multiple threads access shared resources to prevent data corruption. Common methods like start(), join(), sleep() and priority help control thread execution and behavior.
1. Hamid Ghorbani Java Advanced Tutorial(Threads) https://ir.linkedin.com/in/ghorbanihamid
١
Threads:
A thread is a facility to allow multiple activities within a single process, it is a nested
sequence of method calls, It shares memory, files and per-process state. Each thread
has its own program counter, stack and local variables.
We use Threads:
To perform asynchronous or background processing
To Increases the responsiveness of GUI applications
To Take advantage of multiprocessor systems
To Simplify program logic when there are multiple independent entities
Life Cycle of a Thread:
A thread goes through various stages in its life cycle. For example, a thread is born,
started, runs, and then dies. The following diagram shows the complete life cycle of a
thread.
Thread implementation:
In java can be achieved in two ways:
1. Extending the java.lang.Thread class.
2.Implementing the java.lang.Runnable Interface.
Extending Thread class:
Thread class provide constructors and methods to create and perform operations on a thread.
2. Hamid Ghorbani Java Advanced Tutorial(Threads) https://ir.linkedin.com/in/ghorbanihamid
٢
1. Create a class that extends Java Thread class.
2. Then override the run() method in your class, the functionality that is expected by the Thread to be
executed is written in the run() method.
3. Use void start() to start a thread by creating a new callstack. By Starting the thread, it moves from
New state to the Runnable state.When the thread gets a chance to execute, its target run() method
will run.
Example:
class ThreadDemo extends Thread{
public void run(){
System.out.println("My thread is in running state.");
}
public static void main(String args[]){
MultithreadingDemo obj=new MultithreadingDemo();
obj.start();
}
}
Implementing the Runnable Interface:
Extending the Thread class will make your class unable to extend other classes, because of the single
inheritance feature in JAVA. However, this will give you a simpler code structure. If you implement Runnable, you
can gain better object-oriented design and consistency and also avoid the single inheritance problems.
For implementing the Runnable interface You will need the following steps:
1. Create a class that implements the Runnable interface.
2. Your class should implement the run() method in the Runnable interface, This method provides an
entry point for the thread and the business logic that is expected by the Thread to be executed is
put inside this method.
3. instantiate a Thread an Object from using the following constructor:
Thread(Runnable threadObj);
4. Use void start() method to start the thread.
Example:
public class MyThread implements Runnable {
public void run(){
System.out.println("thread is running..");
}
public static void main(String[] args) {
Thread t = new Thread(new MyThread());
t.start();
}
Common Thread Methods:
getName(): It is used for Obtaining a thread’s name
3. Hamid Ghorbani Java Advanced Tutorial(Threads) https://ir.linkedin.com/in/ghorbanihamid
٣
setName(String name): Changes the name of the Thread object.
getPriority(): Obtain a thread’s priority
setPriority(int priority): Sets the priority of this Thread object. The possible values are
between 1 and 10.
isAlive(): Determine if a thread is still running. It returns true if the thread is not finished.
join(): Wait for a thread to terminate. When this method called from the parent thread makes
parent thread wait till child thread terminates.
join(long miliseconds): waits for a thread to terminate for the specified miliseconds.
run(): Entry point for the thread
sleep(): suspend a thread for a period of time
start(): start a thread by calling its run() method
dumpStack():Prints the stack trace for the currently running thread, which is useful when
debugging a multithreaded application.
holdsLock(Object x): Returns true if the current thread holds the lock on the given Object.
getState(): returns the state of the thread.
suspend(): is used to suspend the thread(depricated).
resume(): is used to resume the suspended thread(depricated).
stop(): is used to stop the thread(depricated).
interrupt(): Interrupts this thread, causing it to continue execution if it was blocked for any
reason.
isInterrupted(): tests if the thread has been interrupted.
wait():tells the calling thread to give up the monitor and go to sleep
notify(): wakes up the first thread that called wait() on the same object.
notifyAll(): wakes up all the threads that called wait() on the same object. The highest
priority thread will run first.
setDaemon(boolean on): marks the thread as daemon or user thread.
When we create a Thread in java, by default it’s a user thread and if it’s running JVM will not
terminate the program. A daemon thread is a thread that does not prevent the JVM from
4. Hamid Ghorbani Java Advanced Tutorial(Threads) https://ir.linkedin.com/in/ghorbanihamid
۴
exiting when the program finishes but the thread is still running. Daemon threads are used for
background supporting tasks and are only needed while normal threads are executing. If
normal threads are not running and remaining threads are daemon threads then the interpreter
exits. An example for adaemon thread is the garbage collection.
تعريف ديمن نوع از را تردي اگر اما .دهند نمي را برنامه شدن بسته اجازه هستند اجرا حال در زمانيكه تا عادي حالت در ها ترد
.شود نمي برنامه شدن بسته مانع ديگر ترد نوع اين ،كنيم
isDaemon(): tests if the thread is a daemon thread.
Thread Priority:
Each thread has a priority. Priorities are represented by a number between 1 and 10.
3 constants defiend in Thread class:
1. public static int MIN_PRIORITY (No : 1)
2. public static int NORM_PRIORITY (No : 5)
3. public static int MAX_PRIORITY (No :10)
Default priority of a thread is 5 (NORM_PRIORITY).
Example:
MyThread m1 = new MyThread ();
m1.setPriority(Thread.MIN_PRIORITY);
Ending Thread: A Thread ends due to the following reasons:
The thread ends when the run() method finishes its execution.
When the thread throws an Exception or Error that is not being caught in the program.
Java program completes or ends.
Another thread calls stop() methods.
Deadlock
Deadlock is a situation where two or more threads are blocked forever. deadlock situation arises with at
least two threads and two or more resources. A set of processes or threads is said to be deadlocked when
each is waiting for an action that only one of the others can perform.
5. Hamid Ghorbani Java Advanced Tutorial(Threads) https://ir.linkedin.com/in/ghorbanihamid
۵
The thread dump output clearly shows the deadlock situation and threads and resources involved causing
deadlock situation. For analyzing deadlock, we need to look out for the threads with state as BLOCKED and
then the resources it’s waiting to lock. Every resource has a unique ID using which we can find which thread
is already holding the lock on the object.
Avoid Dead Lock condition:
There are some methods by which we can avoid this condition. We can’t completely remove its possibility
but we can reduce.
Avoid Nested Locks : This is the main reason for dead lock. Dead Lock mainly happens when we give locks to
multiple threads. Avoid giving lock to multiple threads if we already have given to one.
Avoid Unnecessary Locks : We should have lock only those members which are required. Having lock on
unnecessarily can lead to dead lock.
Using thread join(long miliseconds) : Dead lock condition appears when one thread is waiting other to finish.
If this condition occurs we can use Thread.join with maximum time you think the execution will take.
دستور از است بهتر ،باشد ديگر ترد اتمام يك منتظر ترد يك است قرار كه وقتيjoin(long miliseconds)ترد اتمام انتظار براي
نمي رخ بست بن و دهد مي ادامه كارش به ترد زمان اتمام از بعد ، ماند مي منتظر را مشخصي زمان يك دستور اين چون .كنيم استفاده
.دهد
Synchronization of Threads
Synchronization in java is the capability to control the access of multiple threads to any shared resource.
Java Synchronization is better option where we want to allow only one thread to access the shared resource.
6. Hamid Ghorbani Java Advanced Tutorial(Threads) https://ir.linkedin.com/in/ghorbanihamid
۶
In many cases concurrently running threads share
data and two threads try to do operations on the
same variables at the same time. This often results
in corrupt data as two threads try to operate on the
same data.
By using the synchronize only one thread can access
the method at a time and a second call will be
blocked until the first call returns or wait() is called
inside the synchronized method.
Syntax to use synchronized block:
synchronized (object reference expression) {
//code block
}
7. Hamid Ghorbani Java Advanced Tutorial(Threads) https://ir.linkedin.com/in/ghorbanihamid
٧
Example:
class Table{
void printTable(int n){
synchronized(this){ //synchronized block
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{ Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}//end of the method
}
class MyThread1 extends Thread{
Table t;
MyThread1(Table t){
this.t=t;
}
public void run(){
t.printTable(5);
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
public class TestSynchronizedBlock1{
public static void main(String args[]){
Table obj = new Table(); //only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
ThreadGroup:
Java provides a convenient way to group multiple threads in a single object. In such way, we can
suspend, resume or interrupt group of threads by a single method call.
8. Hamid Ghorbani Java Advanced Tutorial(Threads) https://ir.linkedin.com/in/ghorbanihamid
٨
Example:
public class ThreadGroupDemo implements Runnable{
public void run() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
ThreadGroupDemo runnable = new ThreadGroupDemo();
ThreadGroup tg1 = new ThreadGroup("Parent ThreadGroup");
Thread t1 = new Thread(tg1, runnable,"one");
t1.start();
Thread t2 = new Thread(tg1, runnable,"two");
t2.start();
Thread t3 = new Thread(tg1, runnable,"three");
t3.start();
System.out.println("Thread Group Name: "+tg1.getName());
tg1.list();
}
}
Important methods of ThreadGroup class
No. Method Description
1) int activeCount() returns no. of threads running in current group.
2) int activeGroupCount() returns a no. of active group in this thread group.
3) void destroy() destroys this thread group and all its sub groups.
4) String getName() returns the name of this group.
5) ThreadGroup getParent() returns the parent of this group.
6) void interrupt() interrupts all threads of this group.
7) void list() prints information of this group to standard console.
Thread Coordination:
Threads are often interdependent. one thread may depend on another thread to complete an operation
or to service a request. For example, a spreadsheet program may run an extensive recalculation as a
separate thread. If a user-interface (UI) thread attempts to update the spreadsheet's display, the UI
thread should coordinate with the recalculation thread, starting the screen update only when the
recalculation thread has successfully completed.
9. Hamid Ghorbani Java Advanced Tutorial(Threads) https://ir.linkedin.com/in/ghorbanihamid
٩
برنامه يه مثال عنوان به .باشند وابسته هم به كارشان ادامه براي ترد دو كه آيد مي پيش مواقعي معموﻻ نويسي برنامه درspreadsheet
ترد اگر حال .دارد محسابات انجام براي ترد يك برنامه اين .بگيريد نظر در را اكسل مانندUIترد با بايد ترد اين ،شود رساني بروز بخواهد
ترد كار اين براي ،دهد نمايش را شده رساني بروز ديتاي بتواند تا باشد داشته همكاري محاسباتUIمحاسبات ترد كه بماند منتظر بايد
.دهد ادامه را كارش بتواند تا شود تمام كارشمنت بايد كارش ادامه براي ترد يك كه عمل اين بههماهنگي ، شود ديگر ترد يك كار اتمام ظر
) ها ترد بينThread Coordination.شود مي گفته (
از استفاده ،ها ترد بين همكاري از ديگري مثالbuffersShared.باشد مي برنامه در
انجام روشهايThread coordination:
1) Conditions, wait& notify
2) Semaphore
3) CountDownLatch
Conditions, wait & notify:
Threads are usually coordinated using a concept known as a condition, or condition variable.
A condition is a state or an event that a thread can not proceed without it. the thread must wait for the
condition to become true before continuing. In Java, this pattern is usually expressed
روش درTread Coordinationدستور از معموﻻwaitدستور از و ترد ماندن منتظر برايnotifyياnotifyAllكردن بيدار براي
شود بيدار يا برود بخوا بايد ترد موقع چه اينكه بررسي براي شود مي استفاده تردها.شود ايجاد بايد شرطي يك معموﻻ
Example:
مثال اگرShared Bufferبگيرم نظر در را،) باشيم داشته بايد ديتا توليدكننده ترد يكproducerكننده مصرف ترد يك و (
)Consumer.(،بافر ظرفيت بودن محدود علت بهاگر همچنين .شود خالي تا باشد منتظر بايد كننده توليد ترد است پر بافر زمانيكه تا
.شود داده قرار بافر در ديتا تا بماند منتظر بايد كننده مصرف ترد نباشد ديتايي بافر در
public class Producer implements Runnable {
private Buffer buffer;
public Producer(Buffer b) {
buffer = b;
}
public void run() {
for (int i=0; i<250; i++) {
buffer.put((char)('A' + (i%26)));
}
}
}
public class Consumer implements Runnable {
private Buffer buffer;
public Consumer(Buffer b) {
buffer = b;
}
public void run() {
for (int i=0; i<250; i++) {
System.out.println(buffer.get());
}
}
}
10. Hamid Ghorbani Java Advanced Tutorial(Threads) https://ir.linkedin.com/in/ghorbanihamid
١
public class Buffer {
private char[] buf; // buffer storage
private int last; // last occupied position
public Buffer(int sz) {
buf = new char[sz];
last = 0;
}
public synchronized void put(char c) {
while(isFull()) {
try {
wait();
}catch(InterruptedException e) { }
}
buf[last++] = c;
notify();
}
public synchronized char get() {
while(isEmpty()) {
try {
wait();
}catch(InterruptedException e) { }
}
char c = buf[0];
System.arraycopy(buf, 1, buf, 0, --last);
notify();
return c;
}
public boolean isFull() {
return (last == buf.length);
}
public boolean isEmpty() {
return (last == 0);
}
} // end of class
CountDownLatch:
CountDownLatch is a concurrency construct that allows one or more threads to wait for a given set of
operations to complete.
A CountDownLatch is initialized with a given count. This count is decremented by calls to the countDown()
method. Threads waiting for this count to reach zero can call one of the await() methods. Calling await()
blocks the thread until the count reaches zero.
CountDownLatchبه سپس و باشند عمليات از مجموعه يك شدن كامل منتظر تا دهد مي اجازه ترد چند يا يك به كه است كﻼسي
همزماني نويسي برنامه در .بدهند ادامه كارشانlatchمقدار اين سپس .كند مي دريافت مقدار يك آغاز براي و باشد مي سوييچ يك مانند
متد فراخواني بار هر باcountDown()سپس و برسد صفر به شمارنده اين مقدار تا مانند مي منتظر ها ترد .كند مي شدن كم به شروع
روش اين .كنند مي خود پروسس ادامه به شروعو بوده امن روش يكبرقبلي روش خﻼف)wait/notify(به نيازsynchronized
.ندارد فرايند بودن امن براي بﻼك كردن
public class Waiter implements Runnable{
CountDownLatch latch = null;
public Waiter(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Waiter Released");
}
}
public class Decrementer implements Runnable {
CountDownLatch latch = null;
public Decrementer(CountDownLatch latch) {this.latch = latch;
}
public void run() {
try {
Thread.sleep(1000);
this.latch.countDown();
Thread.sleep(1000);
this.latch.countDown();
Thread.sleep(1000);
this.latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args){
CountDownLatch latch = new
CountDownLatch(3);
Waiter waiter = new Waiter(latch);
Decrementer decrementer = new
Decrementer(latch);
new Thread(waiter) .start();
11. Hamid Ghorbani Java Advanced Tutorial(Threads) https://ir.linkedin.com/in/ghorbanihamid
١
new Thread(decrementer).start();
Thread.sleep(4000);
}
مقدار مثال اين درlatch٣كﻼس اينكه از بعد ،شده داده
Decrementerتابع بار سه()countDownكرد فراخواني را،
كﻼسwaiter.دهد مي ادامه و شده ازاد
Schedule periodic tasks:
Tasks can be scheduled for execution in the future. Such tasks can be performed either periodically, or just
once. As well, the first execution can be delayed to a specific time in the future.
There are two different styles of implementing a scheduled task:
ScheduledExecutorService and ScheduledFuture: New Java APIs
Timer and TimerTask: Old Java APIs
ScheduledExecutorService:
ScheduledExecutorService is an ExecutorService which can schedule tasks to run after a delay, or to execute
repeatedly with a fixed interval of time (periodically) in between each execution. Tasks are executed
asynchronously by a worker thread.
Since ScheduledExecutorService is an interface, you will have to use its implementation, in order to use it:
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
ScheduledExecutorService methods:
schedule (Callable task, long delay, TimeUnit timeunit):
The method returns a ScheduledFuture which you can use to either cancel the task before it has started
executing, or obtain the result once it is executed.
schedule (Runnable task, long delay, TimeUnit timeunit)
This method works like the method version taking a Callable as parameter, except a Runnable cannot return a
value, so the ScheduledFuture.get() method returns null when the task is finished.
scheduleAtFixedRate (Runnable, long initialDelay, long period, TimeUnit timeunit)
This method schedules a task to be executed periodically. The task is executed the first time after
the initialDelay, and then recurringly every time the period expires. If any execution of the given task
throws an exception, the task is no longer executed.
scheduleWithFixedDelay (Runnable, long initialDelay, long period, TimeUnit timeunit)
This method works very much like FixedRate method except that the period is interpreted differently. In this
method, the period is interpreted as the delay between the end of the previous execution, until the start
of the next. The delay is thus between finished executions, not between the beginning of executions.
Example:
12. Hamid Ghorbani Java Advanced Tutorial(Threads) https://ir.linkedin.com/in/ghorbanihamid
١
public class MyThread implements Runnable {
private String name;
public MyThread(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void run() {
try {
System.out.println("Doing a task
during : " + name +
" - Time - " +
new Date());
}
catch (Exception e) {
e.printStackTrace();
}
}
} // end of class
public class ScheduledThreadPoolExecutorExample {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
MyThread thread1 = new MyThread("Demo Task 1");
MyThread thread2 = new MyThread("Demo Task 2");
System.out.println("The time is : " + new Date());
try {
// Execute a task after a period of time
executor.schedule(thread1, 5 , TimeUnit.SECONDS);
executor.schedule(thread2, 10 , TimeUnit.SECONDS);
// Execute a task periodically
ScheduledFuture<?> result = executor.scheduleAtFixedRate(thread1, 2, 5,
TimeUnit.SECONDS);
executor.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
e.printStackTrace();
}
executor.shutdown();
}
}