0% found this document useful (0 votes)
6 views8 pages

Java Synchronized Threads Example

This document demonstrates how to use synchronization in Java threads. It shows a Sender class that sends messages and a ThreadedSend class that extends Thread to send messages concurrently. The run method in ThreadedSend synchronizes on the sender object to ensure only one thread can send a message at a time. This prevents messages from being interleaved by multiple threads. Alternate implementations are shown synchronizing the entire send method or using a synchronized block within the method.

Uploaded by

Gowsalya S
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)
6 views8 pages

Java Synchronized Threads Example

This document demonstrates how to use synchronization in Java threads. It shows a Sender class that sends messages and a ThreadedSend class that extends Thread to send messages concurrently. The run method in ThreadedSend synchronizes on the sender object to ensure only one thread can send a message at a time. This prevents messages from being interleaved by multiple threads. Alternate implementations are shown synchronizing the entire send method or using a synchronized block within the method.

Uploaded by

Gowsalya S
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

// A Java program to demonstrate working of

// synchronized.

import [Link].*;

import [Link].*;

// A Class used to send a message

class Sender {

public void send(String msg)

[Link]("Sending\t" + msg);

try {

[Link](1000);

catch (Exception e) {

[Link]("Thread interrupted.");

[Link]("\n" + msg + "Sent");

}
// Class for send a message using Threads

class ThreadedSend extends Thread {

private String msg;

Sender sender;

// Receives a message object and a string

// message to be sent

ThreadedSend(String m, Sender obj)

msg = m;

sender = obj;

public void run()

// Only one thread can send a message

// at a time.

synchronized (sender)

// synchronizing the send object

[Link](msg);
}

// Driver class

class SyncDemo {

public static void main(String args[])

Sender send = new Sender();

ThreadedSend S1 = new ThreadedSend(" Hi ", send);

ThreadedSend S2 = new ThreadedSend(" Bye ", send);

// Start two threads of ThreadedSend type

[Link]();

[Link]();

// wait for threads to end

try {

[Link]();

[Link]();

}
catch (Exception e) {

[Link]("Interrupted");

Output
Sending Hi

Hi Sent
Sending Bye

Bye Sent

Explanation

In the above example, we choose to synchronize the Sender object inside


the run() method of the ThreadedSend class. Alternately, we could define
the whole send() block as synchronized, producing the same result. Then
we don’t have to synchronize the Message object inside the run() method in
ThreadedSend class.
// An alternate implementation to demonstrate
// that we can use synchronized with method also.

class Sender {
public synchronized void send(String msg)
{
[Link]("Sending\t" + msg);
try {
[Link](1000);
}
catch (Exception e) {
[Link]("Thread interrupted.");
}
[Link]("\n" + msg + "Sent");
}
}
We do not always have to synchronize a whole method. Sometimes it is
preferable to synchronize only part of a method. Java synchronized blocks
inside methods make this possible.
// One more alternate implementation to demonstrate
// that synchronized can be used with only a part of
// method

class Sender
{
public void send(String msg)
{
synchronized(this)
{
[Link]("Sending\t" + msg );
try
{
[Link](1000);
}
catch (Exception e)
{
[Link]("Thread interrupted.");
}
[Link]("\n" + msg + "Sent");
}
}
}
Example of the synchronized method by using an anonymous
class

 Java

// Java Pogram to synchronized method by

// using an anonymous class

import [Link].*;

class Test {

synchronized void test_function(int n)

// synchronized method

for (int i = 1; i <= 3; i++) {

[Link](n + i);

try {

[Link](500);

catch (Exception e) {
[Link](e);

// Driver Class

public class GFG {

// Main function

public static void main(String args[])

// only one object

final Test obj = new Test();

Thread a = new Thread() {

public void run() { obj.test_function(15); }

};

Thread b = new Thread() {

public void run() { obj.test_function(30); }


};

[Link]();

[Link]();

Output

16
17
18
31
32
33

Common questions

Powered by AI

The main function in the 'SyncDemo' class demonstrates proper handling of thread termination by utilizing the 'join()' method on both threads 'S1' and 'S2'. The 'join()' method ensures that the main thread waits for the completion of each respective thread before proceeding further. This prevents the main program from terminating prematurely and guarantees that both threads have completed their execution, ensuring orderly shutdown and output consistency .

Synchronizing only part of a method focuses the locking mechanism precisely on the critical section of code interacting with shared resources, reducing the scope of the lock and potential bottlenecks. This can enhance application performance by allowing other non-critical executions to run concurrently, optimizing the use of computational resources and improving system responsiveness .

Using anonymous classes for thread implementation adds simplicity and readability by encapsulating the thread's behavior within the same section of code where the thread is created. This approach suits situations where the thread logic is relatively simple or is only used within a specific local context. However, it can reduce reusability and clarity for complex operations compared to named classes, making debugging and maintenance challenging if not properly managed .

If the threads 'S1' and 'S2' were not synchronized on the 'Sender' object, they could simultaneously access the 'send()' method. This concurrent access could result in interleaving of the 'Sending' and 'Sent' messages, leading to confusion and unpredictable output, such as interference with the sequence, potentially mixing the delivery messages 'Hi' and 'Bye'. This race condition would compromise data consistency and thread safety .

An entire method would be defined as synchronized when the majority or all of its operations involve shared resources that require thread safety. This approach simplifies the code as it automatically synchronizes every call to the method, enforcing a consistent locking policy. It is preferable in situations where the method's logic is tightly coupled and managing concurrency internally would offer negligible performance gains compared to potential maintenance and complexity costs of granular synchronization .

Using 'Thread.sleep()' within a synchronized block can negatively impact concurrency performance since it holds the lock during sleep periods, potentially causing unnecessary delays for other threads waiting on the lock. This introduces a bottleneck that could be highly detrimental in environments demanding high responsiveness and throughput. Appropriate usage entails ensuring the sleep duration is minimal or existing only during critical sections that must avoid releasing the lock temporarily to preserve data integrity .

The output sequence of the threaded 'Test' class example—where numbers from each thread appear in non-interleaved, sequential order—highlights the effects of synchronization by ensuring mutual exclusion. The 'synchronized' method in the 'Test' class enforces that only one thread can execute the 'test_function' at a time, thus preventing any overlap in printing numbers. This guarantees that once a thread starts executing the method, it completes the entire sequence before another thread begins, maintaining orderly and expected results .

The synchronization mechanism ensures thread safety by synchronizing on the 'sender' object inside the 'run()' method of the 'ThreadedSend' class. This means that when one thread is executing the 'send()' method on a given 'Sender' object, other threads must wait for this execution to complete before they can enter the synchronized block. This prevents multiple threads from concurrently accessing shared resources within the synchronized block, thus maintaining data consistency and avoiding race conditions .

Thread interruption handling is critical when using 'Thread.sleep()' because threads can be externally interrupted while asleep, usually due to a request to gracefully shut down or respond to certain conditions. Failing to handle such interruptions may lead to ignored requests for resource release or application control, making systems unresponsive or experiencing deadlocks. By catching 'InterruptedException', the program can take responsible steps, such as releasing locks or cleaning up resources, maintaining robustness and flexibility in handling dynamic runtime conditions .

Synchronizing a method in Java means that the entire method block is locked for synchronization, which is sometimes unnecessary for certain parts of the method. A synchronized block allows more granular control by synchronizing only the critical section of the code, which can lead to better performance as it avoids locking active execution unrelated to shared resources. This provides flexibility and optimizes the synchronization for concurrent executions .

You might also like