0% found this document useful (0 votes)
20 views6 pages

C++ Multithreading Basics and Examples

Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views6 pages

C++ Multithreading Basics and Examples

Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Example #1 Create Thread class

class MyThread1 extends Thread {

public void run()


{

[Link]("Thread1 is running");
}
}

class MyThread2 extends Thread {

public void run()


{

[Link]("Thread2 is running");
}
}
class GFG {

// Main method
public static void main(String[] args)
{

MyThread1 obj1 = new MyThread1();


MyThread2 obj2 = new MyThread2();
[Link]();
[Link]();
}
}
import [Link].*;
Example #2: Implements Runnable
import [Link].*;
class MyThread1 implements Runnable {
public void run()
{
for (int i = 0; i < 5; i++) {

[Link]("Thread1");

try {
// Making the thread pause for a certain
// time using sleep() method
[Link](1000);
}

catch (Exception e) {
}
}
}
}

class MyThread2 implements Runnable {

public void run()


{
for (int i = 0; i < 5; i++) {
[Link]("Thread2");

try {
[Link](1000);
}
catch (Exception e) {
}
}
}
}

public class GFG {

// Main driver method


public static void main(String[] args)
{

Runnable obj1 = new MyThread1();


Runnable obj2 = new MyThread2();

// Creating reference of thread class


// by passing object of Runnable in constructor of
// Thread class
Thread t1 = new Thread(obj1);
Thread t2 = new Thread(obj2);

// Starting the execution of our own run() method


// in the classes above
[Link]();
[Link]();
}
}

class A1 extends Thread


{
public void run ()
{
[Link] ("Thread A");
[Link] ("i in Thread A ");
for (int i = 1; i <= 5; i++)
{
[Link] ("i = " + i);
try
{
[Link] (1000);
}
catch (InterruptedException e)
{
[Link] ();
}
}
[Link] ("Thread A Completed.");
}
}

class B extends Thread


{
public void run ()
{
[Link] ("Thread B");
[Link] ("i in Thread B ");
for (int i = 1; i <= 5; i++)
{
[Link] ("i = " + i);
}
[Link] ("Thread B Completed.");

}
}
public class ThreadLifeCycleDemo
{
public static void main (String[]args)
{
// life cycle of Thread
// Thread's New State
A1 threadA = new A1 ();
B threadB = new B ();

[Link]("Thread state before sleep: " + [Link]());


[Link]("Thread state before sleep: " + [Link]());

// Both the above threads are in runnable state


// Running state of thread A & B
[Link] ();
[Link]("Thread state After sleep: " + [Link]());
[Link]("after starting thread isAlive: "+ [Link]());
// Move control to another thread
[Link] ();
[Link]();
[Link]("after starting thread isAlive: "+ [Link]());
// Blocked State of thread B

try
{
[Link] (1000);
}
catch (InterruptedException e)
{
[Link] ();
}
[Link] ();
[Link] ("Main Thread End");
[Link]("after starting thread isAlive: "+ [Link]());
}
}
‘Thread Priority #1
class SampleThread extends Thread{
public void run() {
[Link]("Inside SampleThread");
[Link]("Current Thread: " + [Link]().getName());
}
}

public class My_Thread_Test {

public static void main(String[] args) {


SampleThread threadObject1 = new SampleThread();
SampleThread threadObject2 = new SampleThread();
[Link]("first");
[Link]("second");

[Link](4);
[Link](Thread.MAX_PRIORITY);

[Link]();
[Link]();

}
}
Thread Priority #2
// Importing the required classes
import [Link].*;

public class ThreadPriorityExample extends Thread


{

// Method 1
// Whenever the start() method is called by a thread
// the run() method is invoked
public void run()
{
// the print statement
[Link]("Inside the run() method");
}

// the main method


public static void main(String argvs[])
{
// Creating threads with the help of ThreadPriorityExample class
ThreadPriorityExample th1 = new ThreadPriorityExample();
ThreadPriorityExample th2 = new ThreadPriorityExample();
ThreadPriorityExample th3 = new ThreadPriorityExample();

[Link]("Priority of the thread th1 is : " + [Link]());

[Link]("Priority of the thread th2 is : " + [Link]());

[Link]("Priority of the thread th2 is : " + [Link]());


[Link](6);
[Link](3);
[Link](9);
[Link]("Priority of the thread th1 is : " + [Link]());
[Link]("Priority of the thread th2 is : " + [Link]());
[Link]("Priority of the thread th3 is : " + [Link]());
[Link]("Currently Executing The Thread : " + [Link]().getName());

[Link]("Priority of the main thread is : " + [Link]().getPriority());

// Priority of the main thread is 10 now


[Link]().setPriority(10);

[Link]("Priority of the main thread is : " + [Link]().getPriority());


}
}

Common questions

Powered by AI

Setting thread priorities allows developers to suggest an execution order for threads based on their importance, potentially improving application performance by favoring critical tasks. However, priorities are highly dependent on the JVM implementation and operating system, as they are merely hints rather than enforced rules. This can lead to unpredictable behavior across different platforms, making it unreliable for precise control of thread execution. The lack of guarantees and cross-platform inconsistency make priority settings beneficial for rough resource allocation but limit their effectiveness as precise scheduling tools .

Extending the Thread class and implementing the Runnable interface are two different approaches to creating threads in Java. Extending Thread allows the class to inherit methods from the Thread class directly and override the run() method to define the thread's task, as shown in class MyThread1 in Source 1. This restricts the class to inheriting from Thread only, limiting class design flexibility. On the other hand, implementing Runnable allows the class to implement run() while still being able to extend another class, supporting more flexible application design. Threads are created using the Thread constructor, passing the Runnable object as an argument, as seen in class MyThread1 implementing Runnable .

Thread priorities in Java indicate the relative importance of threads to be executed by the CPU. Higher priority threads are more likely to be executed before lower priority ones, as seen when setting different priorities for threads using setPriority(). In the provided examples, SampleThread objects are given different priorities, affecting their execution order. However, thread priorities are not guaranteed to strictly dictate execution due to variations in JVM implementations and operating system scheduling. Therefore, while priorities suggest preferred execution order, they should not be relied on for precise control over thread scheduling .

The sleep() method pauses the execution of the current thread for a specified time, moving it from the RUNNING state to the TIMED_WAITING state. This allows other threads to execute while the current thread is paused. In the document example, both MyThread1 and MyThread2 use Thread.sleep(1000) to pause for 1 second between iterations, allowing other processes to utilize CPU time. Sleep does not release any locks held by the thread, unlike waiting methods, and once the specified sleep time is over, the thread transitions back to the RUNNABLE state .

Synchronization in Java ensures that only one thread can access a critical section of code at any given time, preventing concurrent access issues such as race conditions. It provides mutual exclusion and visibility guarantees by acquiring a lock before executing synchronized code and releasing it afterward. This is crucial for maintaining consistent data states across threads and ensuring thread safety. Without synchronization, threads may interleave in undesirable ways, leading to inconsistent outcomes, especially when updating shared resources or data structures .

The join() method allows a thread to wait for the completion of another thread. When a thread calls join() on another thread, it enters the WAITING state until the specified thread finishes executing, ensuring the calling thread does not proceed until another finishes. This is useful in scenarios where a consistent execution sequence is necessary, such as when thread A must complete before threads depending on its results proceed. In ThreadLifeCycleDemo, thread A joins to ensure its completion before moving forward, ensuring the sequence of operations .

Improper use of Thread methods such as start(), interrupt(), and stop() can introduce severe issues in applications. Calling start() more than once on the same thread instance leads to IllegalThreadStateException, while interrupt() can prematurely disrupt a thread's operation, which, if not handled, can lead to inconsistent states or missed functionality. The stop() method, though deprecated, immediately ceases thread execution without guaranteeing proper resource release, often leaving shared resources in inconsistent states. Using these methods incorrectly can compromise application stability and data integrity .

A developer might choose the sleep() method over wait() when a thread needs to pause execution for a specified time without releasing its locks, making sleep() suitable for timing and delay tasks in animations or retries. Contrarily, wait() is used for inter-thread communication, requiring a corresponding notify() or notifyAll() to resume execution, releasing locks upon suspension to allow other threads to operate on the monitor. Sleep is simple and easier to manage when the concern is simply passing time, not waiting for conditions to change .

The yield() method suggests to the thread scheduler that the current thread willingly relinquishes the CPU, allowing other threads of the same or higher priority to execute. Unlike sleep(), yield() does not specify a time duration and only makes the thread ready to run; it can immediately return to the RUNNABLE state if no other threads are ready to execute. In the ThreadLifeCycleDemo class, the yield() method temporarily pauses thread A, giving an opportunity for thread B or other threads to execute .

Using the Thread class directly provides low-level control but may lead to several drawbacks compared to the Executor framework. Direct thread creation can lead to resource contention and poor management of system resources when there's a high volume of short-lived tasks. It lacks functionalities such as task queuing, thread pooling, and reusability that the Executors provide, leading to inadequate scalability and efficiency in thread-intensive applications. Executors abstract these complexities, optimizing performance by managing a pool of threads more effectively .

You might also like