Java Unit 5
Java Unit 5
String Handling in Java: Introduction, Interface Char Sequence, Class String, Methods for Extracting Characters from
Strings, Comparison, Modifying, Searching; Class String Buffer.
Multithreaded Programming: Introduction, Need for Multiple Threads Multithreaded Programming for Multi-core
Processor, Thread Class, Main Thread-Creation of New Threads, Thread States, Thread Priority-Synchronization,
Deadlock and Race Situations, Inter-thread Communication - Suspending, Resuming, and Stopping of Threads.
Java FX GUI: Java FX Scene Builder, Java FX App Window Structure, displaying text and image, event handling, laying
out nodes in scene graph, mouse events
String handling is essential in programming because strings represent text, which is a major
part of almost every application. We need to handle strings for tasks like displaying messages,
taking user inputs, processing data from files, and communicating with other systems. String
handling is mainly required for
Text Processing
• Many applications involve reading and manipulating text data, such as names,
addresses, and messages. We may need to join, split, or format these texts in meaningful
ways.
• In text editing or document applications, string handling allows us to make changes,
search for words, or replace specific parts.
• User input, like names, passwords, and commands, is almost always in text form.
Proper string handling lets us validate, format, and store this input correctly.
• For example, we might need to check if an email address has the correct format, or if a
password meets length requirements.
The CharSequence interface in Java is the parent of several classes like String,
StringBuilder, and StringBuffer, any class implementing CharSequence must define following
abstract methods of CharSequence.
String Class : The String class in Java represents a sequence of characters and is one of the
most commonly used classes for handling text.
Umashankar.5544@[Link]
• Immutability: Strings are immutable in Java, which means once a String object is
created, it cannot be modified. Any operation that seems to modify a string actually
creates a new String object.
• String Pool: Java uses a "string pool" to store string literals, which saves memory by
reusing identical strings. For instance
o String S1 = “Hello”;
o String s2 = “Hello”
// no new memory will be allotted by s2, assigned with address of s1.
Where s1 and s2 will point to same memory locations
• Implements CharSequence: String implements the CharSequence interface, allowing it
to represent a sequence of characters and providing methods to work with characters.
StringBuffer
Equality boolean isEqual = [Link]("Hello"); Convert to String first, then use equals.
Umashankar.5544@[Link]
boolean isEqual = boolean isEqual =
[Link]("hello"); [Link]().equalsIgnoreCase("hello");
Modifying
Searching
Index of String str = "Hello"; StringBuffer buffer = new StringBuffer("Hello");
Character int index = [Link]('e'); int index = [Link]("e");
Output: 1 Output: 1
Index of
int index = [Link]("ll"); int index = [Link]("ll");
Substring
Output: 2 Output: 2
Last Index
String str = "Hello"; StringBuffer buffer = new StringBuffer("Hello");
of
int lastIndex = [Link]('o'); int lastIndex = [Link]("o");
Character
Output: 4 Output: 4
Umashankar.5544@[Link]
Need for Multiple Threads
• Parallel Execution: Multiple threads can run in parallel on different CPU cores,
improving the performance.
• Resource Sharing : Threads within the same process share memory and resources,
making it easier to communicate and exchange information.
• Responsiveness in UI: In user interface (UI) applications, multithreading allows the
UI to remain responsive while performing background tasks (e.g., file uploads,
calculations).
• Improved Throughput: With multiple threads executing concurrently, the overall
throughput of the system increases, allowing more tasks to be completed in a given time
frame.
• Scalability : Applications can be designed to scale with the number of cores. Adding
more cores can lead to proportional performance improvements if the application is
multithreaded.
Multi-core Processors : A multi-core processor contains two or more processing units (cores)
on a single chip, allowing it to perform multiple operations simultaneously.
Multithreaded Programming for Multi-core Processor : Multithreaded programming
involves parallel execution of multiple threads within a single program. With the availability
of multi-core processors, multithreading has become more popular. Multi-Threading allows
different parts of the program to run parallelly and efficiently, by utilizing the multiple
processing cores available.
Thread class : The Thread class is used to create and run threads, enabling multithreading in
Java. It provides various constructors and methods to support thread operations. The Thread
class extends the Object class and implements the Runnable interface.
Some of the Thread class constructors
Constructors of the Thread Class
1. Thread()
Creates a new thread object.
2. Thread(String str)
Creates a new thread object with given user defined name(str) for the thread.
3. Thread(Runnable r)
Creates a new thread by accepting the object of a class that implements
Runnable interface.
4. Thread(Runnable r, String str)
Creates a new thread by accepting the object of a class that implements
Runnable interface with given user defined name(str) for the thread.
Note : Along with these Thread class also supports few other constructors which support
ThreadGroup
Umashankar.5544@[Link]
1. start(): This method begins the execution of the thread. It invokes the run() method
allowing the thread to run concurrently with the main method.
2. run(): This method contains the code that defines the thread's behavior. It must be
overridden to specify what the thread will execute when it is started.
3. sleep(long millis): This static method pauses the currently executing thread for a
specified number of milliseconds. It can throw an InterruptedException if another
thread interrupts the sleeping thread.
4. join(): This method allows one thread to wait for another thread to finish its execution.
When called on a thread, it blocks the calling thread until the specified thread
terminates.
5. isAlive(): This method checks if a thread has been started and has not yet finished its
execution. It returns true if the thread is still running and false otherwise.
6. setPriority(int priority): This method sets the priority of the thread, which can affect
the thread's scheduling. The priority is an integer between Thread.MIN_PRIORITY (1)
and Thread.MAX_PRIORITY (10).
7. getPriority(): This method retrieves the current priority of the thread. It returns an
integer representing the thread's priority level.
8. suspend(): This method is deprecated and was used to temporarily pause a thread's
execution. It can lead to deadlocks and should be avoided, in its place other mechanisms
like wait() and notify() of Object class should be used.
9. resume(): This method is also deprecated and was used to resume a suspended thread.
As with suspend(), it can lead to complications in thread management and should not
be used.
10. stop(): This method is deprecated due to its unsafe nature. It was used to suddenly
terminate a thread, which could lead to deadlock or inconsistent states.
Thread-Creation
Umashankar.5544@[Link]
@Override
public void run()
{
for (int i = 1; i <= 5; i++)
{
[Link]("Count: " + i);
}
}
}
Umashankar.5544@[Link]
// Main class to run the program
public class ThreadExample {
public static void main(String[] args)
{
// Step 4: Create an instance of the MyRunnable class
MyRunnable myRunnable = new MyRunnable();
1. New:
The thread object is created, the state is “New” state, the stage before the start()
method is invoked. Instantiating a thread does not initiate its execution.
Thread thread = new Thread();
2. Runnable:
The thread enters “Runnable” state after invoking the start() method. In this state, the
thread is ready to run, but it may not receive CPU time immediately. The Thread Scheduler
determines when to schedule the thread for execution.
[Link]();
Umashankar.5544@[Link]
3. Blocked:
Threads reaches to the “Blocked” state when they are waiting for a resource lock. This
state occurs when a thread attempts to access an object which locked by another thread.
synchronized (any Object) {
// Critical section
}
4. Waiting:
The “Waiting” state occurs when a thread is waiting for another thread to perform a
particular action. This can be triggered by calling methods like wait() and join(). In the
following example, a thread waits for a notification from another thread.
synchronized (sharedObject) {
wait();
}
5. Timed Waiting:
Similar to the “Waiting” state, “Timed Waiting” involves waiting for a specified
duration. This state occurs when a thread calls sleep() or join() with a specified time duration.
Here, the thread sleeps for one second.
try {
[Link](1000);
} catch (InterruptedException e) {
[Link]();
}
6. Terminated:
The thread enters the “Terminated” state when its run() method completes or if an
uncaught exception occurs. At this point, the thread is no longer alive, and its resources can
be released.
Thread Priority
Thread Priority in Java is used to give preferences to a thread, which helps the thread
scheduler decide how to allocate CPU time among multiple threads. The priority value of a
thread can influence the order in which threads are scheduled for execution, with higher
priority threads generally receiving more CPU time than lower priority ones.
1. Priority Values: Thread priorities are represented by integers in the range of 1 to 10.
The constants provided by the Thread class for these priorities are:
o Thread.MIN_PRIORITY (1): The lowest priority.
o Thread.NORM_PRIORITY (5): The default priority assigned to threads.
o Thread.MAX_PRIORITY (10): The highest priority.
2. Setting Priority: You can set a thread's priority using the setPriority(int priority)
method. This can affect how the thread is scheduled,
Umashankar.5544@[Link]
3. Impact on Scheduling: While a higher priority may increase the chances of a thread
being executed sooner than lower priority threads, it does not guarantee in all times.
The thread scheduler uses its own algorithm, and the actual scheduling can be
influenced by many factors.
4. priority inversion:
Using thread priorities can lead to issues like priority inversion, where a lower-
priority thread holds a resource needed by a higher-priority thread making to wait,
leading to performance issues.
Example Program:
class PriorityExample extends Thread {
public void run()
{
int p = [Link]().getPriority();
for (int i = 1; i <=10000; i++)
{
[Link]("Thread is running with Priority: " + p);
}
}
public static void main(String[] args) {
// Create three threads
PriorityExample thread1 = new PriorityExample();
PriorityExample thread2 = new PriorityExample();
PriorityExample thread3 = new PriorityExample();
// Set different priorities
[Link](Thread.MIN_PRIORITY); // Lowest priority (1)
[Link](Thread.NORM_PRIORITY); // Normal priority (5)
[Link](Thread.MAX_PRIORITY); // Highest priority (10)
// Start threads
[Link]();
[Link]();
[Link]();
}
}
OutPut : The thread with lower priority is more likely terminate after the thread with
high and normal priorities.
Umashankar.5544@[Link]
Race Condition :
A race condition occurs in a multi-threaded environment when two or more threads
attempt to access and modify shared data simultaneously. This can lead to unpredictable
behavior and inconsistent results. For example, if two threads increment the same counter
variable without proper synchronization, the final value may be less than/greater than the
expected because one thread may overwrite the value modified by the other resulting
unexpected results. synchronization is used to avoid race conditions, to ensure that only one
thread can access shared resources at a time.
Synchronization :
Synchronization in Java is a mechanism that is used to control access to shared resources by
multiple threads. It helps prevent thread interference and ensures that only one thread can
access a resource at a time, which is critical for maintaining data integrity and avoiding race
conditions.
Synchronization can be employed in two ways using
i. Synchronized Methods
ii. Synchronized Blocks:
o Synchronized Blocks: You can also synchronize specific blocks of code within a
method to minimize the scope of synchronization, improving performance. This is
done by using the synchronized keyword with an object reference.
public void myMethod() {
synchronized (object) {
// critical section
}
}
Umashankar.5544@[Link]
Example Program for Synchronized methods:
class CounterTest {
private static int counter = 1;
public static synchronized void increment() {
counter++;
}
public static synchronized void decrement() {
counter--;
}
public static void main(String[] args) throws InterruptedException {
Thread incrementThread = new Thread(() -> {
for (int i = 0; i < 100000; i++) {
increment();
}
});
[Link]();
[Link]();
[Link]();
[Link]();
Deadlock :
A deadlock is a situation in a multi-threaded environment where two or more threads
are unable to complete their execution because each thread is waiting for a resource that is held
by another thread. This creates a cycle of dependencies that prevents any of the threads
involved from making progress. For instance, if Thread A holds Resource 1 and waits for
Resource 2, while Thread B holds Resource 2 and waits for Resource 1, neither thread can
continue, leading to a never ending situation. Deadlocks can severely affect system
performance and responsiveness. When locks are applied using Synchronization one has to
carefully inspect the chance of undergoing to deadlock situations.
class Data {
static String resource1 = "CSE";
static String resource2 = "JAVA";
}
Umashankar.5544@[Link]
class Task1 implements Runnable {
public void run()
{
synchronized (Data.resource1)
{
// Attempting to lock resource1
[Link]("Thread 1: locked resource 1");
class DeadlockExample {
public static void main(String[] args) {
// Create instances of Task1 and Task2
Task1 task1 = new Task1();
Task2 task2 = new Task2();
Note : both the threads are waiting for one another leading to deadlock condition.
Umashankar.5544@[Link]
Inter-thread communication:
Inter-thread communication refers to the mechanisms that allow threads to
communicate and coordinate their actions in a multi-threaded environment. It is essential for
managing shared resources and ensuring that threads work together effectively without causing
data inconsistency or race conditions.
Java provides several built-in methods for inter-thread communication, through the Object
class methods as follows:
1. wait(): This method causes the current thread to release the monitor (lock) and wait
until another thread invokes notify() or notifyAll() on the same object. It helps in
pausing the thread until a specific condition is met.
2. notify(): This method wakes up a single thread that is waiting for an resource object. If
multiple threads are waiting, one of them is chosen at random to be awakened.
3. notifyAll(): This method wakes up all the threads that are waiting on the resource
object. allowing them to compete for the monitor lock once it becomes available.
Inter-thread communication is used where threads need to coordinate their actions, such as
producer-consumer problems, where a producer thread generates data and a consumer thread
processes that data. By using these communication methods, developers can create more
efficient and responsive applications.
Suspending: Suspending a thread means temporarily halting its execution without releasing
any resources it holds. The thread can be resumed later.
Deprecation of suspend() - In older Java versions, the suspend() method was used, but it is
deprecated due to the risk of deadlocks. Instead, developers are encouraged to use more
controlled mechanisms, such as flags or synchronization methods, to manage thread
suspension.
Deprecation of resume(): Again, the resume() method was used in older versions, which is
also deprecated. The preferred way to resume execution is to use wait/notify mechanisms or
condition variables, which ensure that the thread can safely continue without causing resource
contention.
Umashankar.5544@[Link]
Stopping: Stopping a thread means terminating its execution, regardless of what the thread is
doing at that moment.
Deprecation of stop(): The stop() method was used for stopping threads, but it is also
deprecated due to potential issues like resource leaks and inconsistent states. Instead, threads
should be stopped gracefully using a flag that signals the thread to complete its current task
and then exit.
Example Program:
class SuspendResumeExample {
public static void main(String[] args) {
ExampleThread thread = new ExampleThread();
[Link]();
try {
// Let the thread run for 5 seconds
[Link](5000);
[Link]("Resuming thread...");
// Resume the thread
[Link]();
} catch (Exception e) {
[Link]("Main thread interrupted.");
}
}
}
Umashankar.5544@[Link]
Java FX GUI :
Java FX App Window Structure
JavaFX is the standard GUI toolkit for Java. It provides advanced features to create
professional and visually appealing UIs. The Java FX App Window Structure contains
• Stages and Scenes:
o The Stage is the top-level container that represents the main window in JavaFX
applications.
o A Scene contains the layout of the components or "nodes" to be displayed within
the Stage.
• Nodes: UI Elements in a JavaFX application (like buttons, text fields, and images) are
represented as nodes. The JavaFX support layouts like HBox, VBox, GridPane, and
BorderPane to organize elements in different arrangements.
• Event Handling: JavaFX provides robust support for handling user interactions
through various events like mouse clicks, key events and action events. Each node can
register event handlers to respond to these actions.
• Styling and Animation: JavaFX supports CSS for styling and customizing the
appearance of nodes, giving flexibility to make the UI visually appealing. It also
includes a rich set of animation classes for creating dynamic UIs.
Umashankar.5544@[Link]
4. Preview Mode: Scene Builder allows users to preview how the application will look at
runtime. This feature helps in testing the layout and UI interactions without compiling
the entire project.
Example of JavaFX and Scene Builder Integration - simple example illustrating the setup:
FXML File ([Link])
<?import [Link]?>
<VBox fx:controller="MyController" spacing="10">
<Button text="Click Me" onAction="#handleButtonClick"/>
<Label fx:id="messageLabel" text="Click the button!" />
</VBox>
Umashankar.5544@[Link]
Controller Class ([Link])
package [Link];
import [Link];
import [Link];
@FXML
@FXML
import [Link];
import [Link];
import [Link];
import [Link];
@Override
[Link](scene);
[Link]();
launch(args);
Umashankar.5544@[Link]
Displaying Text And Image
Image and Text:
• Image: The Image class is used to load the image file. The "file:[Link]" is
used to display if image is in the same directory as the code. Update this path if the image
is elsewhere.
• ImageView: This displays the image in the window, and optional resizing is done
with setFitWidth and setFitHeight.
• Label: The Label displays text, here set to "Hello, JavaFX!".
• VBox: Arranges the text label and image vertically with 10 pixels of spacing between
them.
Umashankar.5544@[Link]
// Add both the text and the image to a layout
VBox root = new VBox(10); // VBox with 10px spacing
[Link]().addAll(textLabel, imageView);
Event Handling
In JavaFX, event handling is a way to handle user interactions with the application's
graphical user interface (GUI). Events are actions or occurrences that happen within an
application, like mouse clicks, key presses, or button clicks.
1. Events
• Events are signals generated when users interact with GUI components. In JavaFX,
these interactions can include actions like clicking a button, moving the mouse, pressing
a key, or even window operations like closing.
Umashankar.5544@[Link]
Event Types in JavaFX
JavaFX categorizes events into several types:
• Action Events: Triggered by components like buttons, menu items, or text fields when
the user performs an action (e.g., clicking a button).
• Mouse Events: Generated by mouse interactions, including clicks, entering or exiting
a component, dragging, pressing, or releasing the mouse.
• Key Events: Triggered when a user presses, types, or releases a key.
• Window Events: Occur when a window is opened, closed, or minimized.
3. Event Handling Process
The process of handling events in JavaFX involves three main steps:
• Registering an Event Handler: Attach an event handler to a specific component. For
example, attaching an event handler to a button to respond to clicks.
• Defining the Event Handler: Create code that specifies what should happen when the
event occurs. This is usually done by implementing the EventHandler interface.
• Processing the Event: The event handler’s handle method is automatically invoked
when the specified event occurs, executing the response defined.
4. The EventHandler Interface
• The EventHandler<T extends Event> interface is a functional interface that contains a
single method, handle(Event event).
• This handle method is where the code for handling the event is written.
• To define an event handler, we can create a class that implements EventHandler and
override the handle method.
5. Attaching Event Handlers
Event handlers can be attached to nodes (like buttons, text fields) or scenes. Here’s an example
using a button:
Button button = new Button("Click Me");
[Link](new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
[Link]("Button Clicked!");
}
});
Umashankar.5544@[Link]
Laying Out Nodes In Scene Graph :
Layouts in JavaFX :
In JavaFX, laying out nodes in the scene graph involves arranging your UI components (nodes)
in a structured way using layout panes. The scene graph is a hierarchical tree structure that
represents the visual elements of your application, where each node can be a UI component or
a layout container.
Umashankar.5544@[Link]
3. GridPane: Arranges nodes in a grid format (rows and columns).
GridPane gridPane = new GridPane();
[Link](node1, columnIndex, rowIndex);
// specify the column and row index for each node
[Link](node2, columnIndex, rowIndex);
4. BorderPane: Divides the area into five regions (top, bottom, left, right, center).
Umashankar.5544@[Link]
Note: Components will be stacked one above the other in StackPane
Mouse Events
Event Handling
Event handling in JavaFX is a core concept that allows you to create interactive
applications. By responding to user actions such as mouse clicks, key presses, and other events,
you can control the behavior of your application.
Event Sources: UI components that generate events (e.g., buttons, text fields).
Event Types: Different types of events, such as ActionEvent, MouseEvent, KeyEvent, etc.
Event Handlers: Methods that define what happens in response to an event.
Umashankar.5544@[Link]
Basic Steps for Event Handling
Define Event Logic: Implement the logic that will execute when the event occurs.
Mouse Event Handling In JavaFX, mouse events allow you to respond to various mouse
actions, such as clicks, movements, and button presses. You can handle these events by
attaching event handlers to your UI components.
Mouse Enter: Triggered when the mouse pointer enters the component area.
setOnMouseEntered()
Mouse Exit: Triggered when the mouse pointer exits the component area.
setOnMouseExited()
Mouse Dragged: Triggered when the mouse is dragged while a button is pressed.
setOnMouseDragged()
Example
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
Umashankar.5544@[Link]
// Handle mouse entered event
[Link](event -> {
[Link]("-fx-background-color: lightblue;");
[Link]("Mouse Entered!");
});
// Create a scene
Scene scene = new Scene(vbox, 300, 200);
Umashankar.5544@[Link]