[go: up one dir, main page]

0% found this document useful (0 votes)
40 views179 pages

OOPS Through JAVA - Unit5

Uploaded by

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

OOPS Through JAVA - Unit5

Uploaded by

Gousejan Shaik
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 179

Unit 5

String , Multithreaded, JDBC and Java FX GUI

SYED MUSTHAFA BYTEXL


1. Introduction to Strings in Java
Definition:
In Java, a String is an object that represents a sequence of characters. Java provides a robust and
flexible API for handling strings, allowing various operations such as concatenation, comparison, and
manipulation. Strings are immutable, meaning once created, their content cannot be changed.
Understanding how to work with strings is essential for many programming tasks.

What are Strings in Java?


Strings in Java are objects that store sequences of characters. Each character is stored in 16 bits using
UTF-16 encoding. A string in Java functions similarly to an array of characters.

Example:

String name = "Test";

This creates a string with the value "Test".


Ways of Creating a String
There are two primary ways to create a string in Java:

1. String Literal: When you create a string using a string literal, Java checks the string constant pool. If the
string already exists, it reuses the existing string object. Otherwise, it creates a new one.
Example:

String demoString = "-";

2. Using the new Keyword: This approach creates a new string object in heap memory, separate from
the string constant pool.
Example:

String demoString = new String("TestString");

In this case, a new string object is created in the heap memory, and the literal "TestString" is placed in
the string constant pool.

String Interfaces and Classes


1. CharSequence Interface: The CharSequence interface represents a sequence of characters. Classes
that implement this interface include:

• String
• StringBuffer
• StringBuilder
Example:
CharSequence seq = "Hello, World!";

2. String Class: The String class represents immutable sequences of characters. Operations on strings
create new string objects rather than modifying the original string.

Example:
String str = "Immutable";

3. StringBuffer Class: StringBuffer is mutable and thread-safe, making it suitable for use in multi-threaded
environments.

Example:
StringBuffer buffer = new StringBuffer("Mutable");

4. StringBuilder Class: StringBuilder is mutable and not thread-safe. It is used in single-threaded scenarios
for better performance.
Example:

StringBuilder builder = new StringBuilder("Efficient");


String Tokenization
StringTokenizer Class: The StringTokenizer class is used to break a string into tokens.

Example:
import java.util.StringTokenizer;

public class TokenizerExample {


public static void main(String[] args) {
StringTokenizer tokenizer = new StringTokenizer("Java StringTokenizer Example");
while (tokenizer.hasMoreTokens()) {
System.out.println(tokenizer.nextToken());
}
}
}
StringJoiner Class
The StringJoiner class constructs a sequence of characters (strings) separated by a delimiter, with
optional prefix and suffix.

Example:
import java.util.StringJoiner;

public class JoinerExample {


public static void main(String[] args) {
StringJoiner joiner = new StringJoiner(", ", "[", "]");
joiner.add("Apple").add("Banana").add("Cherry");
System.out.println(joiner.toString()); // Output: [Apple, Banana, Cherry]
}
}
Immutable Strings
In Java, strings are immutable. This means once a string object is created, its state cannot be changed.
Operations that modify strings actually create new string objects.

Example:

public class ImmutableExample {


public static void main(String[] args) {
String s = "Sachin";
s = s.concat(" Tendulkar");
System.out.println(s); // Output: Sachin Tendulkar
}
}

Memory Allocation of Strings


String Literal: Stored in the String constant pool. Java reuses these objects to save memory.

Example:
String demoString = "Test";

Using new Keyword: Creates a new object in the heap memory, separate from the string constant pool.
Example:

String demoString = new String("Test");

To store this string in the constant pool, you can use intern():

String internedString = demoString.intern();

Java String Pool


The Java String Pool is a special memory area within the heap where Java stores string literals. When
a new string object is created, the String Pool first checks if an identical string already exists in the
pool. If a matching string is found, it returns the reference to the existing string. If not, a new string
object is created, added to the pool, and its reference is returned. This process optimizes memory
usage and enhances performance by avoiding redundant string objects.

Example:
Consider the following scenario:
String s1= "Apple";
String s2= "Mango";
String s3= "Apple";

In this case, "Apple" and "Mango" are stored in the pool as literals. When the third string, also
"Apple," is created, the String Pool returns the reference to the existing "Apple" object rather than
creating a new one.

Immutability of Strings
Unlike other data types in Java, strings are immutable. This means that once a string object is created,
its value cannot be altered. This immutability allows for the sharing of string instances, reducing
memory usage and improving efficiency.

For example:
String str1 = "abc";
is equivalent to:
char[] data = {'a', 'b', 'c'};
String str2 = new String(data);

Both snippets of code result in the creation of the same string object, demonstrating how string
literals and string objects can be used interchangeably.

Inbuilt Methods of the String Class


Java provides several methods for manipulating strings. Some of these methods include operations
for concatenation, substring extraction, and searching within strings.

Practice Programs
Program 1: Count the Number of Words in a String

public class WordCount {


public static void main(String[] args) {
String sentence = "This is a test sentence";
String[] words = sentence.split(" ");
System.out.println("Number of words: " + words.length);
}
}

Program 2: Reverse a String

public class ReverseString {


public static void main(String[] args) {
String original = "ReverseMe";
String reversed = new StringBuilder(original).reverse().toString();
System.out.println("Reversed string: " + reversed);
}
}
Program 3: Check if Two Strings are Anagrams

import java.util.Arrays;

public class AnagramCheck {


public static void main(String[] args) {
String str1 = "listen";
String str2 = "silent";

char[] arr1 = str1.toCharArray();


char[] arr2 = str2.toCharArray();

Arrays.sort(arr1);
Arrays.sort(arr2);

boolean result = Arrays.equals(arr1, arr2);


System.out.println("Are anagrams: " + result);
}
}

Do It Yourself

1. Write a Java program to check if a given string is a palindrome.


2. Write a Java program to find the length of a string without using the length() method.
3. Write a Java program to count the number of vowels and consonants in a string.
4. Write a Java program to convert a string to uppercase and lowercase.

Quiz

1. Which method is used to concatenate two strings in Java?

A) combine()
B) concat()
C) append()
D) join()

Answer: B) concat()

2. What is the output of the following code?

String str = "Hello";


str = str.concat(" World");
System.out.println(str);

A) Hello
B) World
C) Hello World
D) HelloWorld

Answer: C) Hello World

3. Which class is used to create a mutable sequence of characters in Java?

A) String
B) StringBuilder
C) CharSequence
D) StringBuffer

Answer: B) StringBuilder

4. What does the intern() method do for a string object?

A) Creates a new string object


B) Returns the original string object
C) Adds the string to the string constant pool
D) Deletes the string from memory

Answer: C) Adds the string to the string constant pool

5. Which of the following methods is used to split a string into an array of substrings?

A) split()
B) divide()
C) partition()
D) tokenize()

Answer: A) split()

Interface CharSequence in Java


The CharSequence interface in Java is a fundamental part of the Java programming language. It
represents a readable sequence of characters and is implemented by several classes in the Java
standard library, including String, StringBuilder, StringBuffer, and CharBuffer. Understanding
CharSequence is essential for working with text in Java, as it provides a uniform way to access
sequences of characters.

Overview of CharSequence Interface


Definition:

The CharSequence interface is used to represent a sequence of characters. It provides a common


interface for classes that implement sequences of characters, allowing various character-based
operations to be performed in a consistent manner.
Syntax:

public interface CharSequence {


int length();
char charAt(int index);
CharSequence subSequence(int start, int end);
String toString();
}

Methods:

1. int length()

Description: Returns the length of the sequence of characters.


Syntax: int length();
Example:

CharSequence cs = "Hello";
int length = cs.length(); // 5

2. char charAt(int index)


Description: Returns the character at the specified index.
Syntax: char charAt(int index);
Example:

CharSequence cs = "Hello";
char ch = cs.charAt(1); // 'e'

3. CharSequence subSequence(int start, int end)

Description: Returns a new CharSequence that is a subsequence of this sequence.


Syntax: CharSequence subSequence(int start, int end);
Example:

CharSequence cs = "Hello";
CharSequence sub = cs.subSequence(1, 4); // "ell"

4. String toString()

Description: Returns a String that represents the sequence of characters.


Syntax: String toString();
Example:

CharSequence cs = "Hello";
String str = cs.toString(); // "Hello"
Implementations of CharSequence
1. String

Description: The String class implements CharSequence and represents immutable sequences of characters.
Example:

String str = "Hello World";


int length = str.length(); // 11

2. StringBuilder

Description: The StringBuilder class implements CharSequence and represents mutable sequences of
characters.
Example:

StringBuilder sb = new StringBuilder("Hello");


sb.append(" World");
CharSequence cs = sb; // StringBuilder implements CharSequence

3. StringBuffer

Description: Similar to StringBuilder, but StringBuffer is synchronized and thread-safe.


Example:

StringBuffer sbf = new StringBuffer("Hello");


sbf.append(" World");
CharSequence cs = sbf; // StringBuffer implements CharSequence

4. CharBuffer

Description: The CharBuffer class implements CharSequence and provides a buffer of characters.
Example:

CharBuffer cb = CharBuffer.wrap("Hello World");


CharSequence cs = cb; // CharBuffer implements CharSequence

Practice Programs
1. Example Program 1: Length of CharSequence

public class CharSequenceExample {


public static void main(String[] args) {
CharSequence cs = "Engineering";
System.out.println("Length: " + cs.length()); // Output: Length: 11
}
}
2. Example Program 2: Character at Specific Index

public class CharSequenceExample {


public static void main(String[] args) {
CharSequence cs = "Technology";
System.out.println("Character at index 4: " + cs.charAt(4)); // Output: Character at index 4: n
}
}

3. Example Program 3: SubSequence

public class CharSequenceExample {


public static void main(String[] args) {
CharSequence cs = "Computer";
CharSequence sub = cs.subSequence(3, 7);
System.out.println("SubSequence: " + sub); // Output: SubSequence: pute
}
}

4. Example Program 4: Convert CharSequence to String

public class CharSequenceExample {


public static void main(String[] args) {
CharSequence cs = "Science";
String str = cs.toString();
System.out.println("String: " + str); // Output: String: Science
}
}
Do It Yourself

1. Write a Java program to find the length of a CharSequence object.


2. Write a Java program to get the character at index 7 of a CharSequence object.
3. Write a Java program to extract a subsequence from a CharSequence object from index 2 to index 5.
4. Write a Java program to convert a CharSequence to a String and print it.
5. Write a Java program to demonstrate the usage of CharSequence with StringBuilder.

Quiz

1. Which class in Java does NOT implement the CharSequence interface?

a) String
b) StringBuilder
c) StringBuffer
d) ArrayList

Answer: d) ArrayList

2. What does the charAt(int index) method of CharSequence return?

a) A String
b) A CharSequence
c) A char
d) An int

Answer: c) A char

3. Which method of CharSequence returns a subsequence of the current sequence?

a) subSequence(int start, int end)


b) substring(int start, int end)
c) split(String regex)
d) replace(CharSequence target, CharSequence replacement)

Answer: a) subSequence(int start, int end)

4. Which of the following classes implements CharSequence and is mutable?

a) String
b) StringBuffer
c) StringBuilder
d) Both b and c

Answer: d) Both b and c


5. Given the following code snippet, what is the output?

CharSequence cs = "Programming";
System.out.println(cs.subSequence(0, 11));

a) Programming
b) Programmi
c) Programming
d) Programmi

Answer: a) Programming

3. Class String

Class String
Overview: The String class is a final class in Java that represents a sequence of characters. It provides a
rich set of methods to perform operations on strings such as concatenation, comparison, and
searching.

Key Methods:

length(): Returns the length of the string.


charAt(int index): Returns the character at the specified index.
substring(int beginIndex, int endIndex): Returns a substring from the specified beginIndex to endIndex.
concat(String str): Concatenates the specified string to the end of the current string.
toUpperCase(): Converts all characters to uppercase.
toLowerCase(): Converts all characters to lowercase.

Syntax:

public final class String {


public int length();
public char charAt(int index);
public String substring(int beginIndex, int endIndex);
public String concat(String str);
public String toUpperCase();
public String toLowerCase();
}

Example:

String str = "Hello, World!";


int length = str.length(); // 13
char ch = str.charAt(7); // 'W'
String substr = str.substring(7, 12); // "World"
String upperStr = str.toUpperCase(); // "HELLO, WORLD!"
String lowerStr = str.toLowerCase(); // "hello, world!"
Here’s a table listing the methods categorized by their operations:

Category Methods
charAt(int index)
substring(int beginIndex)
substring(int beginIndex, int endIndex)
Methods for Extracting Characters from getChars(int srcBegin, int srcEnd, char[] dst, int
Strings dstBegin)
equals(Object anObject)
equalsIgnoreCase(String anotherString)
compareTo(String anotherString)
Comparison Methods compareToIgnoreCase(String anotherString)
concat(String str)
replace(char oldChar, char newChar)
replace(CharSequence target, CharSequence
replacement)
toLowerCase()
toUpperCase()
trim()
strip()
Modifying Methods stripLeading()
indexOf(int ch)
indexOf(int ch, int fromIndex)
indexOf(String str)
indexOf(String str, int fromIndex)
lastIndexOf(int ch)
lastIndexOf(int ch, int fromIndex)
lastIndexOf(String str)
lastIndexOf(String str, int fromIndex)
contains(CharSequence sequence)
startsWith(String prefix)
startsWith(String prefix, int toffset)
Searching Methods endsWith(String suffix)
append(String str)
insert(int offset, String str)
delete(int start, int end)
deleteCharAt(int index)
reverse()
replace(int start, int end, String str)
Class StringBuffer Methods toString()
4. Methods for Extracting Characters from Strings

Methods for Extracting Characters from Strings


Java provides several methods to extract characters and substrings from a String object. These methods
are useful for manipulating and retrieving portions of a string.
Key Methods

1. charAt(int index)

• Syntax: public char charAt(int index)


• Description: Returns the character at the specified index.
• Parameters: index – the index of the character to return.
• Returns: The character at the specified index.

Example:

public class CharAtExample {


public static void main(String[] args) {
String str = "Hello, World!";
char ch = str.charAt(7); // 'W'
System.out.println("Character at index 7: " + ch);
}
}

Output:

Character at index 7: W

2. substring(int beginIndex)

• Syntax: public String substring(int beginIndex)


• Description: Returns a new string that is a substring of this string starting from the specified beginIndex
to the end of the string.
• Parameters: beginIndex – the beginning index, inclusive.
• Returns: The substring from the beginIndex to the end of the string.

Example:

public class SubstringBeginExample {


public static void main(String[] args) {
String str = "Hello, World!";
String substr = str.substring(7); // "World!"
System.out.println("Substring from index 7: " + substr);
}
}

Output:
Substring from index 7: World!
substring(int beginIndex, int endIndex)

• Syntax: public String substring(int beginIndex, int endIndex)


• Description: Returns a new string that is a substring of this string from the specified beginIndex to
endIndex - 1.
• Parameters: beginIndex – the beginning index, inclusive; endIndex – the ending index, exclusive.
• Returns: The substring from beginIndex to endIndex - 1.

Example:

public class SubstringRangeExample {


public static void main(String[] args) {
String str = "Hello, World!";
String substr = str.substring(7, 12); // "World"
System.out.println("Substring from index 7 to 12: " + substr);
}
}

Output:

Substring from index 7 to 12: World

4. getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)

• Syntax: public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
• Description: Copies characters from this string into the specified character array.
• Parameters:
• srcBegin – the starting index, inclusive.
• srcEnd – the ending index, exclusive.
• dst – the destination array.
• dstBegin – the start offset in the destination array.
• Returns: void.

Example:

public class GetCharsExample {


public static void main(String[] args) {
String str = "Hello, World!";
char[] buffer = new char[5];
str.getChars(7, 12, buffer, 0); // "World"
System.out.println("Characters copied: " + new String(buffer));
}
}

Output:
Characters copied: World
Explanations
1. charAt(int index):

Retrieves a single character from the string based on the specified index. The index is zero-based, meaning
the first character is at index 0. If the index is out of range (negative or greater than the length of the string),
it throws IndexOutOfBoundsException.

substring(int beginIndex):

Extracts a substring from the specified beginning index to the end of the string. This method is useful when
you need to get a portion of a string starting from a specific point.

substring(int beginIndex, int endIndex):

Extracts a substring between the specified beginIndex (inclusive) and endIndex (exclusive). This method is
useful for getting a specific range of characters from a string.

getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin):

Copies a specific range of characters from the string into a character array. This method is useful when you
need to extract multiple characters at once and place them into an existing character array.

Do It Yourself

1. Write a Java program that takes a string input from the user and prints the character at the
index specified by the user.

2. Write a Java program to extract and print the first 10 characters of a given string using substring.

3. Write a Java program that copies characters from index 3 to 8 of a string into a character array and
prints the array.

4. Create a Java program that takes a string and prints all substrings starting from index 2 and ending at
different positions of the string.

5. Write a Java program to extract a substring from the end of a string and print it.

Quiz

1. Which method returns the character at the specified index of a string?

A) substring()
B) charAt()
C) getChars()
D) indexOf()
Answer: B) charAt()
2. Which method is used to extract a portion of a string between specified indices?

A) charAt()
B) substring()
C) getChars()
D) contains()

Answer: B) substring()

3. What does the getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) method do?

A) Replaces characters in a string.


B) Copies characters from a string into a character array.
C) Retrieves a substring.
D) Returns the length of a string.

Answer: B) Copies characters from a string into a character array.

4. What will be the output of str.substring(2, 5) where str is "Java Programming"?

A) ava
B) va
C) va
D) va

Answer: B) va

5. Which method would you use to get a substring from the start to the end of the string?

A) substring(int beginIndex)
B) substring(int beginIndex, int endIndex)
C) charAt(int index)
D) getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)

Answer: A) substring(int beginIndex)

5. Methods for Comparing Strings

Methods for Comparing Strings in Java


Overview
Java provides several methods to compare strings to check for equality or determine the ordering of
strings. These methods are essential for many operations in Java programming, such as sorting,
searching, and validating user input.
Key Methods
1. equals(Object obj)

• Syntax: public boolean equals(Object obj)


• Description: Compares the current string with the specified object for equality. Returns true if the
strings are equal, false otherwise.
• Parameters: obj – the object to be compared with this string.
• Returns: true if the strings are equal, false otherwise.

Example:

public class EqualsExample {


public static void main(String[] args) {
String str1 = "Hello";
String str2 = "Hello";
String str3 = "World";

System.out.println(str1.equals(str2)); // true
System.out.println(str1.equals(str3)); // false
}
}

Output:

true
false

2. equalsIgnoreCase(String anotherString)

• Syntax: public boolean equalsIgnoreCase(String anotherString)


• Description: Compares the current string with the specified string, ignoring case considerations.
• Parameters: anotherString – the string to compare with this string.
• Returns: true if the strings are equal, ignoring case; false otherwise.

Example:

public class EqualsIgnoreCaseExample {


public static void main(String[] args) {
String str1 = "Hello";
String str2 = "HELLO";
String str3 = "World";

System.out.println(str1.equalsIgnoreCase(str2)); // true
System.out.println(str1.equalsIgnoreCase(str3)); // false
}
}
Output:
true
false

3. compareTo(String anotherString)

• Syntax: public int compareTo(String anotherString)


• Description: Compares the current string with the specified string lexicographically.
• Parameters: anotherString – the string to be compared.
• Returns: A negative integer, zero, or a positive integer as this string is less than, equal to, or greater than
the specified string.

Example:

public class CompareToExample {


public static void main(String[] args) {
String str1 = "Apple";
String str2 = "Banana";
String str3 = "Apple";

System.out.println(str1.compareTo(str2)); // Negative value


System.out.println(str1.compareTo(str3)); // 0
System.out.println(str2.compareTo(str1)); // Positive value
}
}

Output:

Negative value
0
Positive value

4. compareToIgnoreCase(String anotherString)

• Syntax: public int compareToIgnoreCase(String anotherString)


• Description: Compares the current string with the specified string, ignoring case considerations.
• Parameters: anotherString – the string to be compared.
• Returns: A negative integer, zero, or a positive integer as this string is less than, equal to, or greater than
the specified string, ignoring case.

Example:

public class CompareToIgnoreCaseExample {


public static void main(String[] args) {
String str1 = "Apple";
String str2 = "banana";
String str3 = "APPLE";
System.out.println(str1.compareToIgnoreCase(str2)); // Negative value
System.out.println(str1.compareToIgnoreCase(str3)); // 0
System.out.println(str2.compareToIgnoreCase(str1)); // Positive value
}
}

Output:

Negative value
0
Positive value

Explanations:
1. equals(Object obj):

Purpose: Determines if two strings have the same sequence of characters. It checks for case-sensitive
equality.
Usage: Useful for checking if two strings are exactly the same.

equalsIgnoreCase(String anotherString):

Purpose: Compares two strings while ignoring case differences. This method is useful when case-
insensitivity is required.
Usage: Useful for case-insensitive comparisons such as user authentication or case-insensitive searches.

compareTo(String anotherString):

Purpose: Provides a lexicographic comparison between two strings. This method helps in sorting strings and
determining their order.
Usage: Useful for sorting operations and determining the relative order of strings.

compareToIgnoreCase(String anotherString):

Purpose: Compares two strings lexicographically while ignoring case differences. It helps in sorting strings
without case sensitivity.
Usage: Useful for case-insensitive sorting or comparisons.

Do It Yourself

1. Write a Java program to compare two strings using the equals method and print the result.

2. Write a Java program to compare two strings using the equalsIgnoreCase method and print the result.

3. Write a Java program to compare two strings using the compareTo method and display whether the
first string is less than, equal to, or greater than the second string.
4. Write a Java program that sorts an array of strings ignoring case and prints the sorted array.

5. Write a Java program to compare two strings using the compareToIgnoreCase method and print
whether the first string is less than, equal to, or greater than the second string.

Quiz

1. Which method is used to compare two strings for equality considering case sensitivity?

A) compareTo()
B) equalsIgnoreCase()
C) equals()
D) compareToIgnoreCase()

Answer: C) equals()

2. Which method compares two strings lexicographically, ignoring case differences?

A) equals()
B) compareTo()
C) compareToIgnoreCase()
D) equalsIgnoreCase()

Answer: C) compareToIgnoreCase()

3. What does str1.compareTo(str2) return when str1 is lexicographically less than str2?

A) 0
B) A positive integer
C) A negative integer
D) Null

Answer: C) A negative integer

4. Which method would you use to perform a case-insensitive comparison of two strings?
A) equals()
B) compareTo()
C) compareToIgnoreCase()
D) startsWith()

Answer: C) compareToIgnoreCase()

5. If str1.compareTo(str2) returns a positive value, what does it indicate?

A) str1 is equal to str2


B) str1 is lexicographically greater than str2
C) str1 is lexicographically less than str2
D) There is an error in comparison

Answer: B) str1 is lexicographically greater than str2

String Modifying Methods in Java


Java provides a set of methods to modify strings. Unlike some other languages, Java strings are
immutable, meaning that once a string is created, it cannot be modified. Instead, methods for
modifying strings return a new string with the desired changes. Below are detailed explanations and
examples of various string modifying methods available in Java.

Key Methods
1. concat(String str)
Syntax: public String concat(String str)
Description: Concatenates the specified string to the end of the current string.
Parameters: str – the string to be concatenated.
Returns: A new string that is the concatenation of the current string and the specified string.

Example:

public class ConcatExample {


public static void main(String[] args) {
String str1 = "Hello";
String str2 = "World";
String result = str1.concat(" ").concat(str2);
System.out.println(result); // Output: Hello World
}
}

Explanation:
Used to combine two strings into one.
Useful for creating a new string that is a combination of existing strings.
replace(char oldChar, char newChar)
Syntax: public String replace(char oldChar, char newChar)
Description: Replaces each occurrence of the specified character in the current string with the new
character.
Parameters:
oldChar – the character to be replaced.
newChar – the character to replace oldChar.
Returns: A new string with all occurrences of oldChar replaced by newChar.

Example:
public class ReplaceCharExample {
public static void main(String[] args) {
String str = "Hello World";
String result = str.replace('o', 'a');
System.out.println(result); // Output: Hella Warld
}
}

Explanation:
Used to replace a specific character in the string with another character.
Useful for making character-based substitutions.
replace(CharSequence target, CharSequence replacement)
Syntax: public String replace(CharSequence target, CharSequence replacement)
Description: Replaces each substring of the current string that matches the specified sequence with the
specified replacement sequence.
Parameters:
target – the sequence to be replaced.
replacement – the sequence to replace target.
Returns: A new string with all occurrences of target replaced by replacement.

Example:

public class ReplaceSequenceExample {


public static void main(String[] args) {
String str = "Hello World";
String result = str.replace("World", "Java");
System.out.println(result); // Output: Hello Java
}
}

Explanation:
Replaces a substring with another substring.
Useful for making more complex replacements within a string.
toLowerCase()
Syntax: public String toLowerCase()
Description: Converts all characters in the current string to lowercase.
Returns: A new string with all characters converted to lowercase.

Example:

public class ToLowerCaseExample {


public static void main(String[] args) {
String str = "Hello World";
String result = str.toLowerCase();
System.out.println(result); // Output: hello world
}
}

Explanation:
Converts all characters in a string to lowercase.
Useful for standardizing text to a common case for comparison or display.
toUpperCase()
Syntax: public String toUpperCase()
Description: Converts all characters in the current string to uppercase.
Returns: A new string with all characters converted to uppercase.

Example:

public class ToUpperCaseExample {


public static void main(String[] args) {
String str = "Hello World";
String result = str.toUpperCase();
System.out.println(result); // Output: HELLO WORLD
}
}

Explanation:
Converts all characters in a string to uppercase.
Useful for standardizing text to a common case for comparison or display.
trim()
Syntax: public String trim()
Description: Removes any leading and trailing whitespace from the current string.
Returns: A new string with leading and trailing whitespace removed.

Example:

public class TrimExample {


public static void main(String[] args) {
String str = " Hello World ";
String result = str.trim();
System.out.println(result); // Output: Hello World
}
}

Explanation:
Removes unnecessary spaces at the start and end of the string.
Useful for cleaning up user input or formatting text.
strip()
Syntax: public String strip()
Description: Removes leading and trailing whitespace from the current string.
Returns: A new string with leading and trailing whitespace removed. This method uses Unicode whitespace
characters.

Example:

public class StripExample {


public static void main(String[] args) {
String str = " Hello World ";
String result = str.strip();
System.out.println(result); // Output: Hello World
}
}
Explanation:
Similar to trim(), but strip() handles Unicode whitespace characters.
Useful for more comprehensive whitespace removal.
stripLeading()
Syntax: public String stripLeading()
Description: Removes leading whitespace from the current string.
Returns: A new string with leading whitespace removed.

Example:

public class StripLeadingExample {


public static void main(String[] args) {
String str = " Hello World";
String result = str.stripLeading();
System.out.println(result); // Output: Hello World
}
}

Explanation:
Removes spaces only from the beginning of the string.
Useful for cleaning up leading spaces without affecting trailing spaces.

Practice Program:

import java.util.Scanner;

public class StringModifier {


public static void main(String[] args) {
Scanner sc = new Scanner(System.in);

// Input two strings from the user


System.out.print("Enter the first string: ");
String str1 = sc.nextLine();
System.out.print("Enter the second string: ");
String str2 = sc.nextLine();

// 1. Concatenating the two strings


String concatenated = str1.concat(" ").concat(str2);
System.out.println("Concatenated String: " + concatenated);

// 2. Replace a character in the concatenated string


System.out.print("Enter the character to be replaced: ");
char oldChar = sc.next().charAt(0);
System.out.print("Enter the new character: ");
char newChar = sc.next().charAt(0);
String replacedChar = concatenated.replace(oldChar, newChar);
System.out.println("String after character replacement: " + replacedChar);
// 3. Replace a substring in the concatenated string
sc.nextLine(); // consume the newline left by next()
System.out.print("Enter the substring to be replaced: ");
String target = sc.nextLine();
System.out.print("Enter the new substring: ");
String replacement = sc.nextLine();
String replacedSubstring = concatenated.replace(target, replacement);
System.out.println("String after substring replacement: " + replacedSubstring);

// 4. Convert to lowercase
String lowerCase = concatenated.toLowerCase();
System.out.println("Lowercase: " + lowerCase);

// 5. Convert to uppercase
String upperCase = concatenated.toUpperCase();
System.out.println("Uppercase: " + upperCase);

// 6. Trim leading and trailing spaces


String strWithSpaces = " " + concatenated + " ";
String trimmed = strWithSpaces.trim();
System.out.println("Trimmed String: " + trimmed);

// 7. Strip leading and trailing spaces (handles Unicode whitespace)


String stripped = strWithSpaces.strip();
System.out.println("Stripped String: " + stripped);

// 8. Strip leading spaces


String stripLeading = strWithSpaces.stripLeading();
System.out.println("Leading Spaces Removed: " + stripLeading);

sc.close();
}
}

Do It Yourself

1. Write a Java program to concatenate the strings "Hello" and "Java" and print the result.

2. Write a Java program to replace all occurrences of the word "Java" with "Programming" in the
string "Learn Java with Java".

3. Write a Java program to extract the substring "World" from the string "Hello World".

4. Write a Java program to convert the string "Java Programming" to lowercase and uppercase, and
print both results.
5. Write a Java program to remove leading and trailing whitespace from the string " Welcome to Java "
and print the result.

Quiz

1. Which method is used to concatenate two strings in Java?


A) concat()
B) append()
C) merge()
D) combine()

Answer: A) concat()

2.What does the replace() method do in Java?

A) Replaces the current string with another string.


B) Replaces characters or substrings in the current string with specified replacements.
C) Replaces the entire string with a new one.
D) Removes characters from the string.

Answer: B) Replaces characters or substrings in the current string with specified replacements.

3.Which method is used to extract a substring from a string in Java?

A) extract()
B) sub()
C) substring()
D) split()
Answer: C) substring()

4.What is the result of calling toLowerCase() on the string "JAVA"?

A) "JAVA"
B) "java"
C) "Java"
D) "jAvA"

Answer: B) "java"

5.What does the trim() method do to a string?

A) Trims the string from both ends.


B) Trims the string from the beginning.
C) Trims the string from the end.
D) Trims the middle of the string.

Answer: A) Trims the string from both ends.


2. String Searching Methods

String Searching Methods

1. indexOf(int ch)
Syntax: public int indexOf(int ch)
Description: Returns the index of the first occurrence of the specified character in the current string.
Parameters:
ch – the character to search for.
Returns: The index of the first occurrence of the character, or -1 if it is not found.

Example:

public class IndexOfCharExample {


public static void main(String[] args) {
String str = "Hello World";
int index = str.indexOf('W');
System.out.println(index); // Output: 6
}
}

Explanation:
Useful for finding the position of a character in a string.

indexOf(int ch, int fromIndex)


Syntax: public int indexOf(int ch, int fromIndex)
Description: Returns the index of the first occurrence of the specified character, starting the search from
the specified index.
Parameters:
ch – the character to search for.
fromIndex – the index to start the search from.
Returns: The index of the first occurrence of the character after the specified index, or -1 if it is not found.

Example:

public class IndexOfCharFromExample {


public static void main(String[] args) {
String str = "Hello World";
int index = str.indexOf('o', 5);
System.out.println(index); // Output: 7
}
}
Explanation:
Allows starting the search from a specific position in the string.

indexOf(String str)
Syntax: public int indexOf(String str)
Description: Returns the index of the first occurrence of the specified substring in the current string.
Parameters:
str – the substring to search for.
Returns: The index of the first occurrence of the substring, or -1 if it is not found.

Example:

public class IndexOfSubstringExample {


public static void main(String[] args) {
String str = "Hello World";
int index = str.indexOf("World");
System.out.println(index); // Output: 6
}
}

Explanation:
Useful for finding the position of a substring within a string.

indexOf(String str, int fromIndex)


Syntax: public int indexOf(String str, int fromIndex)
Description: Returns the index of the first occurrence of the specified substring, starting the search from
the specified index.
Parameters:
str – the substring to search for.
fromIndex – the index to start the search from.
Returns: The index of the first occurrence of the substring after the specified index, or -1 if it is not found.

Example:

public class IndexOfSubstringFromExample {


public static void main(String[] args) {
String str = "Hello World World";
int index = str.indexOf("World", 7);
System.out.println(index); // Output: 12
}
}

Explanation:
Allows starting the search for a substring from a specific position.

lastIndexOf(int ch)
Syntax: public int lastIndexOf(int ch)
Description: Returns the index of the last occurrence of the specified character in the current string.
Parameters:
ch – the character to search for.
Returns: The index of the last occurrence of the character, or -1 if it is not found.

Example:

public class LastIndexOfCharExample {


public static void main(String[] args) {
String str = "Hello World";
int index = str.lastIndexOf('o');
System.out.println(index); // Output: 7
}
}

Explanation:
Useful for finding the last occurrence of a character in a string.

lastIndexOf(int ch, int fromIndex)


Syntax: public int lastIndexOf(int ch, int fromIndex)
Description: Returns the index of the last occurrence of the specified character, searching backwards from
the specified index.
Parameters:
ch – the character to search for.
fromIndex – the index to start the search backwards from.
Returns: The index of the last occurrence of the character before the specified index, or -1 if it is not found.

Example:

public class LastIndexOfCharFromExample {


public static void main(String[] args) {
String str = "Hello World";
int index = str.lastIndexOf('o', 5);
System.out.println(index); // Output: 4
}
}

Explanation:
Allows searching backwards for a character from a specific position.

lastIndexOf(String str)
Syntax: public int lastIndexOf(String str)
Description: Returns the index of the last occurrence of the specified substring in the current string.
Parameters:
str – the substring to search for.
Returns: The index of the last occurrence of the substring, or -1 if it is not found.

Example:
public class LastIndexOfSubstringExample {
public static void main(String[] args) {
String str = "Hello World World";
int index = str.lastIndexOf("World");
System.out.println(index); // Output: 12
}
}

Explanation:
Useful for finding the last occurrence of a substring within a string.

lastIndexOf(String str, int fromIndex)


Syntax: public int lastIndexOf(String str, int fromIndex)
Description: Returns the index of the last occurrence of the specified substring, searching backwards from
the specified index.
Parameters:
str – the substring to search for.
fromIndex – the index to start the search backwards from.
Returns: The index of the last occurrence of the substring before the specified index, or -1 if it is not found.

Example:

public class LastIndexOfSubstringFromExample {


public static void main(String[] args) {
String str = "Hello World World";
int index = str.lastIndexOf("World", 10);
System.out.println(index); // Output: 6
}
}

Explanation:
Allows searching backwards for a substring from a specific position.

contains(CharSequence sequence)
Syntax: public boolean contains(CharSequence sequence)
Description: Checks if the current string contains the specified sequence of characters.
Parameters:
sequence – the sequence to search for.
Returns: true if the sequence is found, otherwise false.

Example:

public class ContainsExample {


public static void main(String[] args) {
String str = "Hello World";
boolean result = str.contains("World");
System.out.println(result); // Output: true
}
}

Explanation:
Determines if a substring exists within a string.

startsWith(String prefix)
Syntax: public boolean startsWith(String prefix)
Description: Checks if the current string starts with the specified prefix.
Parameters:
prefix – the prefix to check.
Returns: true if the string starts with the specified prefix, otherwise false.

Example:

public class StartsWithExample {


public static void main(String[] args) {
String str = "Hello World";
boolean result = str.startsWith("Hello");
System.out.println(result); // Output: true
}
}

Explanation:
Useful for checking if a string begins with a specific substring.

11. startsWith(String prefix, int toffset)


Syntax: public boolean startsWith(String prefix, int toffset)
Description: Checks if the current string starts with the specified prefix, beginning at the specified offset.
Parameters:
prefix – the prefix to check.
toffset – the index to start checking from.
Returns: true if the substring starting from toffset begins with the specified prefix, otherwise false.

Example:

public class StartsWithFromExample {


public static void main(String[] args) {
String str = "Hello World";
boolean result = str.startsWith("World", 6);
System.out.println(result); // Output: true
}
}

Explanation:
Checks if a substring starting at a specific position matches the prefix.
12. endsWith(String suffix)
Syntax: public boolean endsWith(String suffix)
Description: Checks if the current string ends with the specified suffix.
Parameters:
suffix – the suffix to check.
Returns: true if the string

ends with the specified suffix, otherwise false.

Example:

public class EndsWithExample {


public static void main(String[] args) {
String str = "Hello World";
boolean result = str.endsWith("World");
System.out.println(result); // Output: true
}
}

Explanation:
Determines if a string ends with a specific substring.

Do It Yourself

1. Write a program that finds the index of the character 'a' in the given string and prints it.

2. Write a program that finds the index of the substring "Java" in the given string and prints it.

3. Write a program that checks if the string contains the substring "Programming".

4. Write a program that checks if a given string starts with "Hello" and ends with "World".

5. Write a program that finds the last occurrence of the character 'o' in the given string and prints it.

Quiz

1. Which method returns the index of the first occurrence of a specified character in a string?

A) lastIndexOf()
B) indexOf()
C) contains()
D) startsWith()

Answer: B) indexOf()
2. What will str.lastIndexOf("World") return if str = "Hello World World"?

A) 0
B) 6
C) 12
D) -1

Answer: C) 12

3. Which method checks if a string contains a specific sequence of characters?

A) startsWith()
B) endsWith()
C) contains()
D) indexOf()

Answer: C) contains()

4. What will str.startsWith("Hello", 6) return if str = "Hello World"?

A) true
B) false
C) 6
D) -1

Answer: B) false

5. Which method checks if a string ends with a specified suffix?

A) startsWith()
B) contains()
C) endsWith()
D) indexOf()

Answer: C) endsWith()

Class StringBuffer Methods in Java

1. append(String str)
• Syntax: public StringBuffer append(String str)
• Description: Appends the specified string to the end of the current StringBuffer object.
• Parameters:
• str – the string to append.
• Returns: The StringBuffer object itself after appending the string.
Example:

public class AppendExample {


public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello");
sb.append(" World");
System.out.println(sb); // Output: Hello World
}
}

Explanation:
The append method is used to add a string to the end of the existing StringBuffer content.
insert(int offset, String str)
Syntax: public StringBuffer insert(int offset, String str)
Description: Inserts the specified string at the specified position in the current StringBuffer object.
Parameters:
offset – the position at which to insert the string.
str – the string to insert.public class InsertExample {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello World");
sb.insert(6, "Java ");
System.out.println(sb); // Output: Hello Java World
}
}
Returns: The StringBuffer object itself after insertion.

Example:
Explanation:

The insert method allows for inserting a string at a specific position, shifting the existing content.
delete(int start, int end)
Syntax: public StringBuffer delete(int start, int end)
Description: Deletes the characters between the specified start and end indices in the current StringBuffer
object.
Parameters:
start – the starting index (inclusive).
end – the ending index (exclusive).
Returns: The StringBuffer object itself after deletion.

Example:

public class DeleteExample {


public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello Java World");
sb.delete(6, 10);
System.out.println(sb); // Output: Hello World
}
}
Explanation:
The delete method removes a portion of the StringBuffer content between the specified indices.

deleteCharAt(int index)
Syntax: public StringBuffer deleteCharAt(int index)
Description: Deletes the character at the specified index from the current StringBuffer object.
Parameters:
index – the index of the character to delete.
Returns: The StringBuffer object itself after deletion.

Example:

public class DeleteCharAtExample {


public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello World");
sb.deleteCharAt(5);
System.out.println(sb); // Output: HelloWorld
}
}

Explanation:
The deleteCharAt method removes a single character at the specified index.

reverse()
Syntax: public StringBuffer reverse()
Description: Reverses the sequence of characters in the current StringBuffer object.
Returns: The StringBuffer object itself with characters reversed.

Example:

public class ReverseExample {


public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello World");
sb.reverse();
System.out.println(sb); // Output: dlroW olleH
}
}

Explanation:
The reverse method reverses the entire sequence of characters in the StringBuffer.

replace(int start, int end, String str)


Syntax: public StringBuffer replace(int start, int end, String str)
Description: Replaces the characters between the specified start and end indices with the specified string.
Parameters:
start – the starting index (inclusive).
end – the ending index (exclusive).
str – the string to insert.
Returns: The StringBuffer object itself after replacement.

Example:

public class ReplaceExample {


public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello Java World");
sb.replace(6, 10, "Python");
System.out.println(sb); // Output: Hello Python World
}
}

Explanation:
The replace method replaces the content within the specified range with a new string.

toString()
Syntax: public String toString()
Description: Converts the StringBuffer object to a String object.
Returns: A String representing the current StringBuffer content.

Example:

public class ToStringExample {


public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello World");
String str = sb.toString();
System.out.println(str); // Output: Hello World
}
}

Explanation:
The toString method is used to get the string representation of the StringBuffer content.

Practice program:

public class StringBufferMethodsExample {


public static void main(String[] args) {
// Initial StringBuffer
StringBuffer sb = new StringBuffer("Tech");

// 1. Append
sb.append(" Talk");
System.out.println("After append: " + sb); // Output: Tech Talk

// 2. Insert
sb.insert(5, "y ");
System.out.println("After insert: " + sb); // Output: Techy Talk
// 3. Delete
sb.delete(5, 7);
System.out.println("After delete: " + sb); // Output: Tech Talk

// 4. DeleteCharAt
sb.deleteCharAt(4);
System.out.println("After deleteCharAt: " + sb); // Output: TechTalk

// 5. Reverse
sb.reverse();
System.out.println("After reverse: " + sb); // Output: klaThceT

// 6. Replace
sb.replace(0, 3, "Code");
System.out.println("After replace: " + sb); // Output: CodeThceT

// 7. ToString
String str = sb.toString();
System.out.println("StringBuffer to String: " + str); // Output: CodeThceT
}
}

Do It Yourself

1. Write a program that appends " Java" to the given StringBuffer "Hello".

2. Write a program that inserts "Beautiful " at index 6 in the StringBuffer "Hello World".

3. Write a program that deletes characters from index 6 to 11 in the StringBuffer "Hello World Java".

4. Write a program that reverses the content of the StringBuffer "Java Programming".

5. Write a program that replaces characters from index 0 to 4 with "Hi" in the StringBuffer "Hello
World".

Quiz

1. Which method adds a specified string to the end of a StringBuffer?

A) insert()
B) append()
C) replace()
D) reverse()

Answer: B) append()
2. What will sb.delete(0, 5) return if sb = new StringBuffer("Hello World")?
A) Hello World
B) World
C) World
D) ello World

Answer: C) World

3. Which method removes a character at the specified index from a StringBuffer?

A) deleteCharAt()
B) delete()
C) insert()
D) replace()

Answer: A) deleteCharAt()

4. What will sb.reverse() return if sb = new StringBuffer("Java")?


A) Java
B) avaj
C) ajav
D) aJav

Answer: B) avaj

5. Which method converts a StringBuffer object to a String object?

A) toString()
B) toCharArray()
C) substring()
D) append()

Answer: A) toString()
Introduction to Multithreading
Imagine you're juggling multiple tasks at once. You might be cooking dinner, talking on the phone, and
watching TV. Each task is like a separate thread, running independently but within the same context
(your daily life).

In Java, multithreading allows your program to perform multiple tasks simultaneously, just like juggling.
This can make your programs faster and more responsive.

What is Multithreading?

Multithreading is a feature in Java that allows multiple threads to run concurrently within a single process.
This capability enables efficient execution of various tasks and operations in parallel, enhancing the
performance and responsiveness of applications.

Definition: Multithreading is the concurrent execution of two or more threads within a single process. Each
thread shares the same memory space but operates independently, allowing for simultaneous task execution.

Use Cases: Commonly used in applications such as games, animations, and real-time systems where multiple
operations need to be performed concurrently.

Multiprocessing vs. Multithreading

Multitasking is the process of performing multiple tasks simultaneously, and it can be achieved in two
primary ways:
1. Process-Based Multitasking (Multiprocessing):

Definition: Involves executing multiple processes simultaneously, where each process has its own memory
space.

Characteristics:

• Processes are heavyweight and require separate memory allocation.


• High cost of inter-process communication.
• Context-switching involves saving and loading memory maps, registers, etc.
2. Thread-Based Multitasking (Multithreading):

Definition: Involves executing multiple threads within the same process, sharing the same memory space.

Characteristics:

• Threads are lightweight and share the same address space.


• Low cost of inter-thread communication.
• Faster context-switching compared to process-based multitasking.
What is a Thread?

A thread is the smallest unit of processing within a process, also known as a lightweight subprocess. It
represents a separate path of execution within a process.

Characteristics:

Lightweight: Threads share the same memory space and resources of the parent process, reducing
overhead.

Independence: Threads operate independently; an exception in one thread does not affect others.

Shared Memory: Threads share memory and resources, facilitating communication and reducing
memory usage.
Sometimes, the processes might be interdependent for an intermediate result to finish the process.

Types of Threads in Java

In Java, threads are the smallest unit of a process, and they can be categorized into two main types
based on how they are created and executed. Each type of thread serves different purposes depending
on the needs of an application.

1. User Threads

User threads are the main type of threads that are created by the application developer to perform specific
tasks. These threads keep running in the JVM until they finish their execution or are explicitly
terminated. If a user thread is running, the Java Virtual Machine (JVM) will not shut down.

Characteristics of User Threads:

• User threads are initiated by the program.

• The JVM waits for all user threads to complete before shutting down.

• User threads are used to perform specific tasks such as processing data, handling network connections,
etc.

Example:

class MyUserThread extends Thread {


public void run() {
System.out.println("User thread is running");
}
public static void main(String[] args) {
MyUserThread thread = new MyUserThread();
thread.start();
System.out.println("Main thread completed");
}
}
Explanation:
In this example, a user thread (MyUserThread) is created and started. The main thread (main) also runs
and prints a message. The JVM will wait for both the main thread and the user thread to finish before
shutting down.

2. Daemon Threads

Daemon threads are special types of threads in Java that provide services to user threads. These
threads run in the background to support other user threads. A key characteristic of daemon threads is
that the JVM does not wait for them to finish; when all user threads have finished, the JVM
automatically terminates all daemon threads, even if they are still running.

Daemon threads are generally used for background tasks like garbage collection, monitoring, or
logging, where the task doesn’t need to keep the JVM alive.

Characteristics of Daemon Threads:

• Daemon threads run in the background and provide support to user threads.
• They are terminated automatically when no user threads are left running.
• Daemon threads can be set by calling setDaemon(true) on a thread object.

Example:
class MyDaemonThread extends Thread {
public void run() {
while (true) {
System.out.println("Daemon thread is running");
try {
Thread.sleep(1000); // Sleep for 1 second
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyDaemonThread daemonThread = new MyDaemonThread();
daemonThread.setDaemon(true); // Setting thread as daemon
daemonThread.start();

System.out.println("Main thread completed");


}
}

Explanation:
In this example, MyDaemonThread is set as a daemon thread using setDaemon(true). This thread will
run in an infinite loop but will be terminated as soon as the main thread completes. The JVM does not
wait for the daemon thread to finish.

Key Differences Between User Threads and Daemon Threads

Feature User Threads Daemon Threads

Purpose Perform core operations like Perform background operations like


computation. garbage collection.

Termination JVM waits for user threads to JVM terminates daemon threads when no
complete. user threads are left.

Creation Created by the developer for Created by the JVM or set by the
specific tasks. developer using setDaemon().

Default User threads are non-daemon Threads are non-daemon by default, must
Behavior by default. be explicitly set as daemon.

Examples Data processing, file handling, Garbage collection, logging, system


network calls. monitoring.
Setting Daemon Threads

Daemon threads can be set using the setDaemon() method before the thread is started. Once a thread
is started, it cannot be changed to a daemon thread.

Thread t = new Thread();

t.setDaemon(true); // Setting thread as daemon before starting it

t.start();

Lifecycle of a Thread in Java

In Java, a thread goes through five distinct stages in its lifecycle. Each stage plays a crucial role in how
the thread is created, executed, and terminated. Let's explore these stages in detail:

1. New

In the initial stage, called "New," the thread is created but has not yet started. At this point, the thread is
instantiated and remains in the new state until it is assigned a task and started.

2. Runnable

Once the thread is assigned a task, it moves to the "Runnable" state. In this stage, the thread is ready to
execute and is waiting for the CPU to schedule it.

3. Running

When the CPU allocates time to the thread, it enters the "Running" stage. At this point, the thread starts
executing its assigned task and continues until the task is completed or paused.

4. Waiting

In certain situations, a thread may need to wait for another process or resource to become available.
When this happens, the thread enters the "Waiting" state, where it halts temporarily until the
dependent process or resource is ready.

5. Dead

The final stage of a thread's lifecycle is the "Dead" state. Once the thread has completed its execution or
has been explicitly terminated, it enters this state. The thread is no longer active, and the JVM
considers it terminated.
After understanding the lifecycle of a thread, you can now explore how multithreading is implemented
in Java to manage multiple threads efficiently.

Need for Multiple Threads

Multithreading is a core concept in modern programming that involves running multiple threads
concurrently within a single process. Understanding the need for multiple threads is crucial for
developing efficient, responsive, and high-performance applications. Here's a detailed exploration of
why multiple threads are necessary:

1. Improved Performance

a. Concurrent Execution:

Description: Multiple threads allow different tasks to be executed simultaneously, leading to better utilization
of CPU resources.

Example: In a web server, one thread can handle incoming requests, while another processes database
operations concurrently.

b. Efficient Resource Utilization:

Description: Threads share the same memory space and resources of a process, reducing overhead compared
to creating multiple processes.

Example: An application performing multiple calculations simultaneously can utilize threads to distribute the
workload, improving overall performance.
2. Responsiveness

a. User Interface Responsiveness:

Description: Multithreading ensures that the user interface remains responsive while performing background
tasks, such as loading data or performing long computations.

Example: In a graphical user interface (GUI) application, a background thread can handle time-consuming
tasks, allowing the main thread to update the UI smoothly.

b. Real-Time Processing:

Description: Threads can handle real-time data processing without blocking the main execution flow.

Example: In a video game, separate threads can handle rendering, input processing, and game logic, ensuring
smooth gameplay.

3. Efficient Handling of I/O Operations

a. Overlapping I/O Operations:

Description: Threads can perform I/O operations concurrently, avoiding blocking and waiting times associated
with single-threaded execution.

Example: A file processing application can use separate threads to read from and write to files
simultaneously, reducing overall processing time.

b. Handling Multiple Requests:

Description: Servers and networked applications can handle multiple client requests concurrently by assigning
each request to a separate thread.

Example: A web server using threads can handle multiple client connections at once, improving throughput
and response time.

4. Simplified Program Design

a. Decomposing Complex Tasks:

• Description: Large and complex tasks can be broken down into smaller, manageable threads, making the
design and implementation more straightforward.

• Example: A data processing application can divide a large dataset into chunks, with each thread
processing a chunk independently.
b. Asynchronous Operations:

• Description: Threads facilitate asynchronous operations, allowing tasks to run in the background while the
main program continues execution.

• Example: A network application can use threads to perform network communication asynchronously,
enabling other operations to proceed without waiting for the network response.

5. Enhanced Scalability

a. Handling Increased Load:

• Description: Applications designed with multithreading can scale better to handle increased loads by
adding more threads to distribute the workload.

• Example: An e-commerce platform can scale its thread pool to handle a surge in user requests during
peak shopping seasons.

b. Adaptability to Multi-Core Processors:

• Description: Multithreaded applications can take advantage of multi-core processors, where each thread
runs on a separate core, improving parallel execution.

• Example: A computationally intensive application can utilize multiple cores by running different threads
on different cores, accelerating processing.

Multithreaded Programming for Multi-core Processors

Multithreaded programming is particularly beneficial for taking full advantage of multi-core processors.
Here’s an in-depth look at how multithreading works in the context of multi-core processors, and the
benefits it provides:

1. Understanding Multi-core Processors

a. Multi-core Architecture:

• Description: Multi-core processors have multiple processing units (cores) within a single physical chip.
Each core can execute instructions independently.

• Example: A quad-core processor has four cores, allowing it to execute four threads concurrently.
b. Parallel Processing:

• Description: Multi-core processors can perform parallel processing, where multiple tasks or threads are
executed simultaneously.

• Example: Different cores can handle different parts of a computation or different tasks within a program,
speeding up overall execution.

2. Benefits of Multithreading on Multi-core Processors

a. Enhanced Performance:

• Description: Multithreading allows a program to execute multiple threads in parallel, making full use of all
available cores.

• Example: An image processing application can use multiple threads to process different parts of an image
simultaneously, resulting in faster processing times.

b. Improved Responsiveness:

• Description: By running multiple threads concurrently, applications can remain responsive to user inputs
and other tasks even while performing intensive operations.

• Example: A media player can use one thread to handle user interface interactions and another to decode
and play audio/video.

c. Efficient Resource Utilization:

• Description: Multithreading maximizes the utilization of available CPU resources, reducing idle times and
improving throughput.

• Example: A web server can handle multiple client requests concurrently, ensuring that all cores are
utilized effectively.

d. Scalability:

• Description: Multithreaded programs can scale efficiently with the number of cores, providing better
performance as more cores are added.

• Example: A scientific computing application can benefit from additional cores by distributing its
computational tasks across all available cores.

3. Key Concepts in Multithreaded Programming for Multi-core Processors

a. Thread Creation and Management:

Description: Threads are created and managed using thread libraries and frameworks that allow specifying
the tasks to be executed concurrently.

Example: In Java, you can create threads using the Thread class or implementing the Runnable interface.

b. Synchronization:

• Description: To avoid conflicts and ensure data consistency when multiple threads access shared
resources, synchronization mechanisms are used.

• Example: Java provides synchronized methods and blocks to control access to critical sections of code.

c. Thread Scheduling:

• Description: The operating system or runtime environment schedules threads to run on different cores,
balancing the load and optimizing performance.

• Example: Java’s ExecutorService framework provides advanced scheduling and management of thread
pools.

d. Load Balancing:

• Description: Efficient distribution of tasks among threads to ensure balanced workload across all cores.

• Example: A task manager in an application can dynamically assign tasks to threads based on their current
load and availability.

4. Best Practices for Multithreaded Programming


a. Minimize Thread Contention:

• Description: Reduce the time threads spend waiting for access to shared resources to improve
performance.

• Example: Use non-blocking algorithms or reduce the scope of synchronized blocks.

b. Avoid Deadlocks:

• Description: Deadlocks occur when two or more threads are waiting indefinitely for resources held by
each other.

• Example: Ensure a consistent order of acquiring locks and use timeout mechanisms.

c. Use Thread Pools:

• Description: Manage a pool of reusable threads to handle tasks efficiently and avoid the overhead of
creating and destroying threads frequently.

• Example: Java’s ExecutorService provides thread pool management for handling concurrent tasks.

d. Design for Scalability:

• Description: Ensure that the application design allows it to scale effectively with additional cores and
threads.

• Example: Structure the application to handle a variable number of threads and utilize parallelism where
appropriate.

5. Example Code

a. Creating and Running Threads in Java:

// Implementing Runnable interface


class MyTask implements Runnable {
public void run() {
System.out.println("Task executed by: " + Thread.currentThread().getName());
}
}
// Main class
public class MultithreadedExample {
public static void main(String[] args) {
// Creating threads
Thread thread1 = new Thread(new MyTask());
Thread thread2 = new Thread(new MyTask());
// Starting threads
thread1.start();
thread2.start();
}
}

b. Using Thread Pools in Java:


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
// Main class
public class ThreadPoolExample {
public static void main(String[] args) {
// Creating a thread pool
ExecutorService executor = Executors.newFixedThreadPool(2);

// Submitting tasks
executor.submit(() -> System.out.println("Task 1 executed by: " + Thread.currentThread().getName()));
executor.submit(() -> System.out.println("Task 2 executed by: " + Thread.currentThread().getName()));

// Shutting down the executor


executor.shutdown();
}
}
Quiz

1. What is the primary advantage of multithreading over multiprocessing?

A. Increased memory usage


B. Reduced performance
C. Lower overhead due to shared memory
D. Separate memory space
• Answer: C. Lower overhead due to shared memory

2. Which method is used to create a new thread in Java?


A. new Thread()
B. createThread()
C. startThread()
D. initThread()
Answer: A. new Thread()

3. What is a common use case for multithreading?


A. Reading a single file
B. Handling multiple client requests on a server
C. Writing data to a single file
D. Executing a single task sequentially
Answer: B. Handling multiple client requests on a server
Thread Class
Introduction to the Thread Class in Java

In Java, multithreading is supported through the Thread class, which allows the creation and
management of threads within a Java program. A thread is a lightweight subprocess, the smallest unit
of processing. Java's Thread class is a part of the java.lang package, and it provides several methods to
create, control, and manage threads in a concurrent program.

Java provides two ways to create threads:

1. By extending the Thread class.

2. By implementing the Runnable interface.

This material will focus on using the Thread class directly.

1. Creating and Starting a Thread Using the Thread Class

To create a thread by extending the Thread class, you need to follow these steps:

• Define a new class that extends the Thread class.

• Override the run() method to define the task that will be executed by the thread.

• Create an instance of the new class and call the start() method to begin execution.

Syntax:

class MyThread extends Thread {


public void run() {
// Task to be executed by the thread
System.out.println("Thread is running");
}
}public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // Start the thread
}
}
Explanation:

• The run() method is where you define the code that the thread will execute.
• The start() method initiates the thread's execution, calling the run() method internally.

2. Important Methods of the Thread Class


The Thread class provides several methods to control and manage thread behavior:

Method Name Description

start() Starts the thread and calls the run() method.

run() Contains the code that will be executed by the thread.

sleep(long millis) Puts the current thread to sleep for a specified time.

join() Waits for the thread to complete execution.

getName() Returns the name of the thread.

setName(String name) Sets the name of the thread.

getPriority() Returns the priority of the thread.

setPriority(int priority) Sets the priority of the thread.

isAlive() Checks if the thread is still running.

interrupt() Interrupts the thread.

3. Example Programs

Example 1: Basic Thread Creation Using the Thread Class


class MyThread extends Thread {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(i + " from thread " + Thread.currentThread().getName());
}
}
}

public class Main {


public static void main(String[] args) {
MyThread thread1 = new MyThread();
thread1.setName("Thread-1");
thread1.start();

MyThread thread2 = new MyThread();


thread2.setName("Thread-2");
thread2.start();
}
}

Explanation:

• Two threads (thread1 and thread2) are created, and each thread prints numbers from 1 to 5 along with
the thread name.
• The setName() method assigns names to threads, and getName() is used to retrieve the name of the
current thread.

Example 2: Using join() to Wait for Thread Completion

class MyThread extends Thread {


public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println(i + " from " + Thread.currentThread().getName());
try {
Thread.sleep(500); // Sleep for 500 milliseconds
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

public class Main {


public static void main(String[] args) {
MyThread thread1 = new MyThread();
thread1.start();

try {
thread1.join(); // Main thread waits for thread1 to finish
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("Thread 1 has finished executing. Main thread resumes.");


}
}

4. Explanation of Multithreading Concepts

• Context Switching: The process of storing the state of a thread and restoring the state of another thread.
Threads share the CPU in time slices.

• Concurrency: Multiple threads executing simultaneously, giving the illusion of parallelism in a single-core
processor.

• Parallelism: Actual simultaneous execution of threads on different processor cores in multi-core systems.
5. Advantages of Using the Thread Class

• Simplicity: Extending the Thread class provides an easy-to-use abstraction for creating threads.

• Control: Methods like sleep(), join(), and interrupt() offer precise control over thread execution.

Understanding the Thread class is essential for mastering multithreading in Java. The class provides all
the necessary tools to create and control threads. By utilizing multithreading, you can write more
responsive and efficient programs, particularly in environments where parallel processing or
concurrency is required.

Do It Yourself

1. Write a program that creates two threads and prints numbers from 1 to 5 in each thread. Ensure that the
main thread waits for the other two threads to complete using join().

2. Explain the difference between the start() and run() methods in the Thread class.

3. Create a thread using the Thread class to print "Hello, World!" five times with a delay of 1 second
between each print.

4. Write a Java program that demonstrates the use of the isAlive() method to check if a thread is still
running.

5. Write a program that creates three threads, each printing a different message. Use the sleep() method to
introduce a delay between messages.

6. Write a program that demonstrates the usage of getPriority() and setPriority() methods of the Thread
class.

Quiz

1. Which method in the Thread class is used to start a thread?


A. run()

B. begin()

C. start()

D. init()

Answer: C. start()

2. What happens if you call the run() method of a thread directly?

A. new thread is created.

B. The method runs in the same thread without creating a new one.

C. The JVM throws an exception.

D. The program crashes.

Answer: B. The method runs in the same thread without creating a new one.

3. Which of the following methods makes a thread pause for a specified amount of time?

A. sleep()

B. pause()

C. wait()

D. interrupt()

Answer: A. sleep()

4. What is the main difference between Thread.sleep() and Thread.join()?

A. sleep() pauses a thread, while join() waits for a thread to finish.

B. sleep() terminates a thread, while join() pauses a thread.

C. sleep() suspends the JVM, while join() pauses all threads.

D. sleep() runs multiple threads, while join() stops all threads.

Answer: A. sleep() pauses a thread, while join() waits for a thread to finish.
5. Which method would you use to prevent two threads from executing a critical section of code at the
same time?

A. start()
B. synchronized()
C. sleep()
D. yield()
Answer: B. synchronized()

Main Thread and Creation of New Threads in Java


In Java, multithreading allows the concurrent execution of two or more parts of a program to maximize
CPU utilization. Each of these parts is called a thread, and threads run independently. Every Java
program has at least one thread, known as the main thread, and you can create additional threads to
achieve multitasking.

1. Main Thread in Java

When a Java program starts, it always runs the main thread by default. This thread is important
because it performs essential tasks such as handling user input, output, and system events. The main
thread is created by the JVM when the main() method is invoked.

Characteristics of the Main Thread:

• Created by JVM: The JVM automatically creates the main thread when a Java program is executed.
• Entry point: The main() method is the entry point for the main thread.
• Single-threaded execution: By default, all code in the main() method runs in the main thread.
• Control over other threads: The main thread can create and control other threads.

Code Example: Accessing Main Thread

public class MainThreadExample {

public static void main(String[] args) {

// Get the reference of the main thread

Thread mainThread = Thread.currentThread();

System.out.println("Current Thread: " + mainThread);

// Set the name of the main thread

mainThread.setName("Primary Thread");
System.out.println("Renamed Thread: " + mainThread);

// Check the priority of the main thread

System.out.println("Main Thread Priority: " + mainThread.getPriority());

Output:

Current Thread: Thread[main,5,main]

Renamed Thread: Thread[Primary Thread,5,main]

Main Thread Priority: 5

2. Creation of New Threads in Java

In Java, there are two primary ways to create a new thread:

By extending the Thread class

By implementing the Runnable interface

Method 1: Extending the Thread Class

You can create a new thread by extending the Thread class and overriding its run() method. The run()
method contains the code that constitutes the new thread.

Syntax:

class MyThread extends Thread {

public void run() {

// Code that the thread will execute

System.out.println("Thread is running...");

Example:

class MyThread extends Thread {


public void run() {

System.out.println("New thread is running...");

public static void main(String[] args) {

MyThread thread = new MyThread();

thread.start(); // Start the new thread

Output:

New thread is running...

Method 2: Implementing the Runnable Interface

You can also create a thread by implementing the Runnable interface and passing an instance of your
class to a Thread object.

Syntax:

class MyRunnable implements Runnable {

public void run() {

// Code that the thread will execute

System.out.println("Thread is running via Runnable...");

Example:

class MyRunnable implements Runnable {

public void run() {

System.out.println("New thread is running via Runnable...");

}
public static void main(String[] args) {

MyRunnable runnable = new MyRunnable();

Thread thread = new Thread(runnable);

thread.start(); // Start the new thread

Output:

New thread is running via Runnable...

3. Differences Between Thread and Runnable

Feature Extending Thread Implementing Runnable

Inheritance Requires extending Thread Implements Runnable


class. interface, allowing inheritance
of other classes.

Code Limits reusability of code due More flexible and reusable.


Reusability to inheritance restrictions.

Multiple Cannot extend any other class Can implement multiple


Inheritance since Java does not support interfaces along with
multiple inheritance. Runnable.

4. Practice Program: Creating Multiple Threads

Here is a simple program that creates two threads by implementing the Runnable interface.

class TaskOne implements Runnable {

public void run() {

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

System.out.println("TaskOne - Count: " + i);

}
}

class TaskTwo implements Runnable {

public void run() {

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

System.out.println("TaskTwo - Count: " + i);

public class MultipleThreadsExample {

public static void main(String[] args) {

Thread thread1 = new Thread(new TaskOne());

Thread thread2 = new Thread(new TaskTwo());

thread1.start();

thread2.start();

Expected Output:

TaskOne - Count: 1

TaskTwo - Count: 1

TaskOne - Count: 2

TaskTwo - Count: 2

...

TaskOne - Count: 5
TaskTwo - Count: 5

Do It Yourself

1. Write a Java program to create a new thread by extending the Thread class and display a message from the
new thread.
2. Create a Java program using the Runnable interface to print numbers from 1 to 10 in a separate thread.
3. What are the differences between creating a thread by extending Thread and implementing Runnable?
4. Write a Java program that creates two threads using the Runnable interface. One thread should print even
numbers and the other should print odd numbers.
5. Explain the lifecycle of a thread in Java. Provide an example.

Quiz

1. Which of the following is true about multithreading in Java?

• a) Threads run sequentially.


• b) Java does not support multithreading.
• c) Threads run concurrently.
• d) Threads do not share resources.

Answer: c) Threads run concurrently.

2. Which method is used to start a thread in Java?

• a) run()
• b) start()
• c) execute()
• d) begin()

Answer: b) start()

3. Which of the following is NOT a state in the lifecycle of a thread?

• a) New
• b) Running
• c) Suspended
• d) Terminated

Answer: c) Suspended

4. How can you create a thread in Java?

• a) By extending the Thread class.


• b) By implementing the Runnable interface.
• c) Both a and b.
• d) None of the above.

Answer: c) Both a and b.

5. What is the return type of the start() method in the Thread class?

• a) void
• b) int
• c) boolean
• d) Thread

Answer: a) void

Thread States in Java


In Java, a thread can be in one of several states throughout its lifecycle. These states are defined by the
Thread.State enumeration, and understanding them is crucial for writing efficient, thread-safe programs.
Java thread states include the following:

1. New
2. Runnable
3. Blocked
4. Waiting
5. Timed Waiting
6. Terminated

Each state represents a distinct phase in a thread’s life, from creation to execution, pausing, and finally
termination.

1. New State

When a thread is created but not yet started, it is in the New state. At this point, the thread has not started
executing the run() method.

• Syntax:

Thread t1 = new Thread(); // New thread created

• Example:

class MyThread extends Thread {

public void run() {

System.out.println("Thread is running...");
}

public class Main {

public static void main(String[] args) {

Thread t1 = new MyThread(); // Thread in new state

2. Runnable State

Once the thread's start() method is called, it enters the Runnable state. In this state, the thread is ready to
run but waiting for CPU time to be allocated by the thread scheduler.

• Syntax:

t1.start(); // Thread moves from New to Runnable

• Example:

class MyThread extends Thread {

public void run() {

System.out.println("Thread is running...");

public class Main {

public static void main(String[] args) {

Thread t1 = new MyThread();

t1.start(); // Thread moves to Runnable state

3. Blocked State

A thread enters the Blocked state when it tries to access a synchronized block or method that another
thread is currently holding. The thread remains blocked until the monitor lock is released by the other
thread.
• Syntax:

synchronized (object) {

// Critical section

• Example:

class SharedResource {

synchronized void sharedMethod() {

System.out.println(Thread.currentThread().getName() + " is executing");

class MyThread extends Thread {

SharedResource resource;

MyThread(SharedResource resource) {

this.resource = resource;

public void run() {

resource.sharedMethod();

public class Main {

public static void main(String[] args) {

SharedResource resource = new SharedResource();

MyThread t1 = new MyThread(resource);

MyThread t2 = new MyThread(resource);

t1.start();

t2.start(); // One of the threads will be blocked


}

4. Waiting State

A thread is in the Waiting state when it is waiting indefinitely for another thread to perform a specific
action. For example, a thread might call the wait() method, waiting for a notification from another
thread.

Syntax:

synchronized (object) {

object.wait(); // Thread enters Waiting state

Example:

class SharedResource {

synchronized void waitMethod() throws InterruptedException {

wait(); // Thread enters waiting state

synchronized void notifyMethod() {

notify(); // Notifies waiting threads

public class Main {

public static void main(String[] args) {

SharedResource resource = new SharedResource();

Thread t1 = new Thread(() -> {

try {

resource.waitMethod();

} catch (InterruptedException e) {

e.printStackTrace();
}

});

t1.start();

Thread t2 = new Thread(resource::notifyMethod);

t2.start(); // Notifies t1 to leave the waiting state

5. Timed Waiting State

A thread enters the Timed Waiting state when it is waiting for a specified amount of time. This occurs
when methods like sleep(long millis), wait(long millis), join(long millis), or parkNanos(long nanos) are
called.

• Syntax:

Thread.sleep(1000); // Timed waiting for 1 second

• Example:

class MyThread extends Thread {

public void run() {

try {

System.out.println("Thread is sleeping for 2 seconds");

Thread.sleep(2000); // Enters timed waiting state

System.out.println("Thread is awake");

} catch (InterruptedException e) {

e.printStackTrace();

public class Main {

public static void main(String[] args) {


MyThread t1 = new MyThread();

t1.start();

6. Terminated State

Once a thread finishes its execution or is terminated by the stop() method, it moves into the Terminated
state. A terminated thread cannot be restarted.

• Syntax:

t1.stop(); // Terminates the thread (deprecated method)

• Example:

class MyThread extends Thread {

public void run() {

System.out.println("Thread is executing...");

public class Main {

public static void main(String[] args) {

MyThread t1 = new MyThread();

t1.start(); // Starts the thread

try {

t1.join(); // Main thread waits for t1 to finish

} catch (InterruptedException e) {

e.printStackTrace();

System.out.println("Thread t1 has terminated");

}
}

Thread Lifecycle Diagram

A useful diagram to understand the lifecycle of a thread can be found here. (Note: Replace with actual
link if providing resources.)

Practice Program

class MyThread extends Thread {

public void run() {

try {

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

System.out.println("Thread " + Thread.currentThread().getName() + " in state: " +


Thread.currentThread().getState());

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

public class Main {

public static void main(String[] args) {

Thread t1 = new MyThread();

System.out.println("Thread t1 in state: " + t1.getState()); // NEW state

t1.start();

System.out.println("Thread t1 in state: " + t1.getState()); // RUNNABLE state

try {

t1.join(); // Main thread waits for t1 to finish

} catch (InterruptedException e) {

e.printStackTrace();
}

System.out.println("Thread t1 in state: " + t1.getState()); // TERMINATED state

Do It Yourself

1. What are the different states a thread can be in throughout its lifecycle?
2. Write a program to demonstrate the use of sleep() and wait() in Java threads.
3. What is the difference between the Runnable and Blocked states in Java threads?
4. Explain how a thread moves from the Waiting state to the Runnable state.

Quiz

1. Which of the following methods can move a thread from the Timed Waiting state to the Runnable state?

• a) sleep()
• b) notify()
• c) start()
• d) yield()
• Answer: b) notify()

2. Which state represents a thread that has finished execution?

• a) New
• b) Runnable
• c) Terminated
• d) Blocked
• Answer: c) Terminated

3. Which method causes a thread to enter the Waiting state?

• a) sleep()
• b) join()
• c) wait()
• d) start()
• Answer: c) wait()
4. What happens when start() is called on a thread in the New state?

• a) The thread moves to the Running state.


• b) The thread moves to the Runnable state.
• c) The thread remains in the New state.
• d) The thread terminates.
• Answer: b) The thread moves to the Runnable state.

5. Which state does a thread enter when it’s trying to access a synchronized block held by another thread?

• a) Blocked
• b) Timed Waiting
• c) Terminated
• d) Runnable
• Answer: a) Blocked

Thread Priority in Java


Introduction

In Java, threads are assigned priorities to determine the order in which they are scheduled for execution
by the thread scheduler. The thread scheduler uses these priorities to decide when each thread should
run. Thread priorities in Java are integers ranging from MIN_PRIORITY (1) to MAX_PRIORITY (10),
with NORM_PRIORITY (5) as the default.

Threads with higher priority are generally executed in preference to those with lower priority. However,
thread priority does not guarantee the precise order of execution because thread scheduling is platform-
dependent and is controlled by the underlying OS.

Syntax for Setting Thread Priority

public final void setPriority(int newPriority)

Parameters:

• newPriority: This integer value sets the priority of the thread. It must be between 1
(Thread.MIN_PRIORITY) and 10 (Thread.MAX_PRIORITY).

Examples

1. Basic Example of Thread Priority:

class MyThread extends Thread {

public void run() {

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

System.out.println(Thread.currentThread().getName() + " - Priority: " +


Thread.currentThread().getPriority());
}

public class ThreadPriorityDemo {

public static void main(String[] args) {

MyThread thread1 = new MyThread();

MyThread thread2 = new MyThread();

MyThread thread3 = new MyThread();

thread1.setPriority(Thread.MIN_PRIORITY); // Priority 1

thread2.setPriority(Thread.NORM_PRIORITY); // Priority 5

thread3.setPriority(Thread.MAX_PRIORITY); // Priority 10

thread1.start();

thread2.start();

thread3.start();

Output:

Thread-0 - Priority: 1

Thread-1 - Priority: 5

Thread-2 - Priority: 10

2. Thread Priority with Runnable Interface:

class MyRunnable implements Runnable {

public void run() {

System.out.println(Thread.currentThread().getName() + " - Priority: " +


Thread.currentThread().getPriority());

}
}

public class RunnableThreadPriority {

public static void main(String[] args) {

Thread thread1 = new Thread(new MyRunnable());

Thread thread2 = new Thread(new MyRunnable());

Thread thread3 = new Thread(new MyRunnable());

thread1.setPriority(Thread.MIN_PRIORITY); // Priority 1

thread2.setPriority(Thread.NORM_PRIORITY); // Priority 5

thread3.setPriority(Thread.MAX_PRIORITY); // Priority 10

thread1.start();

thread2.start();

thread3.start();

Explanation

• Thread Prioritization: In the above examples, thread1 is given the lowest priority
(Thread.MIN_PRIORITY), while thread3 is assigned the highest (Thread.MAX_PRIORITY). Although
thread priority influences scheduling, it doesn't guarantee that a higher priority thread will always run first.

• Platform Dependence: Thread scheduling and priority management are handled by the OS, and different
operating systems may have different policies on how threads are prioritized and executed.

Thread Priority Constants in Java

• Thread.MIN_PRIORITY: 1 (The lowest possible priority a thread can have).


• Thread.NORM_PRIORITY: 5 (The default priority assigned to threads).
• Thread.MAX_PRIORITY: 10 (The highest possible priority a thread can have).
Key Points

1. Threads can have their priorities changed using setPriority().


2. The default thread priority is Thread.NORM_PRIORITY (5).
3. Priority is just a suggestion to the thread scheduler, and it doesn’t guarantee execution order.
4. It is possible to create threads with the same priority, in which case the OS schedules them based on factors
like time slices or internal algorithms.

Practice Program

class PriorityTest extends Thread {

public void run() {

System.out.println("Running Thread: " + Thread.currentThread().getName() +

", Priority: " + Thread.currentThread().getPriority());

public class TestThreadPriority {

public static void main(String[] args) {

PriorityTest t1 = new PriorityTest();

PriorityTest t2 = new PriorityTest();

PriorityTest t3 = new PriorityTest();

t1.setPriority(Thread.MIN_PRIORITY); // Setting minimum priority

t2.setPriority(Thread.NORM_PRIORITY); // Setting normal priority

t3.setPriority(Thread.MAX_PRIORITY); // Setting maximum priority

t1.start();

t2.start();

t3.start();

}
Do It Yourself

1. Write a Java program that creates three threads with different priorities and prints the thread name and
priority.
2. What is the default thread priority in Java, and how can it be changed?
3. Explain how thread priorities influence thread scheduling.
4. How do thread priorities differ across platforms? Give an example of how this can affect program behavior.
5. Modify a multithreaded Java program where all threads have the same priority and observe the execution
order.

Quiz

1. What is the default priority assigned to a new thread in Java?

• A) 1
• B) 5
• C) 10
• D) 0

Answer: B) 5

2. Which method is used to set the priority of a thread in Java?

• A) setPriority()
• B) changePriority()
• C) threadPriority()
• D) updatePriority()

Answer: A) setPriority()

3. Which of the following is the maximum priority that a thread can have in Java?

• A) 10
• B) 5
• C) 1
• D) 100

Answer: A) 10

4. If two threads have the same priority, what decides their execution order?

• A) Thread priority alone


• B) The underlying OS's thread scheduler
• C) Thread name
• D) None of the above
Answer: B) The underlying OS's thread scheduler

5. Which of the following constants represents the minimum priority for a thread?

• A) Thread.MIN_PRIORITY
• B) Thread.LOW_PRIORITY
• C) Thread.MIN_PR
• D) Thread.PRIORITY_LOW

Answer: A) Thread.MIN_PRIORITY

4. Synchronization

Synchronization in Java

Introduction

In Java, synchronization is a mechanism that ensures that multiple threads can access shared resources
safely, preventing data inconsistency. When multiple threads access shared data or resources
concurrently, thread interference and memory consistency errors can occur. Synchronization helps by
allowing only one thread to access the resource at a time, maintaining thread safety.

Java provides two types of synchronization:

1. Process synchronization – controls access to shared resources.


2. Thread synchronization – ensures that two or more threads don't execute critical sections of code
simultaneously.

Why Synchronization is Needed

When multiple threads access shared resources (e.g., objects, variables), synchronization is necessary to:

1. Avoid thread interference – This happens when one thread changes the shared data while another
thread is using it.
2. Ensure consistency – Prevents inconsistencies that arise from unsynchronized access to shared data by
multiple threads.

Types of Synchronization in Java

1. Synchronized Method: The entire method is locked for one thread at a time. Once one thread enters
the synchronized method, no other thread can enter any synchronized method of the same object.

2. Synchronized Block: Synchronizes only a specific block of code, allowing finer control over the
synchronization.
Syntax for Synchronization

1. Synchronized Method:

synchronized returnType methodName() {

// synchronized code

2. Synchronized Block:

synchronized(object) {

// synchronized code block

Example of Synchronized Method

class Table {

// Synchronized method to print table of a number

synchronized void printTable(int n) {

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

System.out.println(n * i);

try {

Thread.sleep(400); // Simulating time delay

} catch (InterruptedException e) {

System.out.println(e);

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 TestSynchronization {

public static void main(String[] args) {

Table obj = new Table(); // Shared resource (table object)

MyThread1 t1 = new MyThread1(obj);

MyThread2 t2 = new MyThread2(obj);

t1.start();

t2.start();

}
Output:

10

15

20

25

100

200

300

400

500

In the above example, the printTable() method is synchronized, so only one thread can execute it at a
time, preventing data inconsistency.

Example of Synchronized Block

class Table {

// Method that contains synchronized block

void printTable(int n) {

synchronized (this) {

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

System.out.println(n * i);

try {

Thread.sleep(400); // Simulating time delay

} catch (InterruptedException e) {

System.out.println(e);

}
}

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 TestSynchronizationBlock {

public static void main(String[] args) {

Table obj = new Table(); // Shared resource (table object)

MyThread1 t1 = new MyThread1(obj);

MyThread2 t2 = new MyThread2(obj);


t1.start();

t2.start();

In this case, only the critical part of the method (synchronized block) is synchronized, allowing more
granular control over thread access.

Picture for Visualization

You can visualize thread synchronization through flow diagrams:

• Synchronization Diagram: Click here for a sample image of thread synchronization

Explanation

In Java, synchronization prevents thread interference and provides consistent results when multiple
threads work on shared resources. In the examples above, we use the synchronized keyword to lock the
shared resource (Table object) so that only one thread can access the resource at a time.

Practice Program

class Counter {

private int count = 0;

// Synchronized increment method

synchronized void increment() {

count++;

int getCount() {

return count;

class MyCounterThread extends Thread {


Counter counter;

MyCounterThread(Counter counter) {

this.counter = counter;

public void run() {

for (int i = 0; i < 1000; i++) {

counter.increment();

public class SynchronizedCounter {

public static void main(String[] args) throws InterruptedException {

Counter counter = new Counter(); // Shared resource

MyCounterThread t1 = new MyCounterThread(counter);

MyCounterThread t2 = new MyCounterThread(counter);

t1.start();

t2.start();

t1.join();

t2.join();

System.out.println("Final Count: " + counter.getCount());

In this practice program, two threads increment a shared counter. Due to synchronization, the final count
will be 2000, preventing race conditions.

Do It Yourself
1. Write a Java program to demonstrate the use of a synchronized method.
2. Modify the Counter example to demonstrate thread interference by removing synchronization. What issue
arises?
3. Explain the difference between a synchronized method and a synchronized block in Java.
4. Why is thread synchronization necessary? Give an example of thread interference.
5. Write a program using synchronized blocks to achieve thread-safe access to a shared resource.

Quiz

1. What does the synchronized keyword in Java do?

• A) Allows multiple threads to run simultaneously on the same object.


• B) Prevents thread interference by allowing only one thread to execute a block of code at a time.
• C) Increases the speed of thread execution.
• D) All of the above.

Answer: B) Prevents thread interference by allowing only one thread to execute a block of code at a
time.

2. What is the primary purpose of thread synchronization in Java?

• A) To make threads execute faster.


• B) To allow multiple threads to access shared resources simultaneously.
• C) To prevent thread interference and ensure data consistency.
• D) To slow down thread execution.

Answer: C) To prevent thread interference and ensure data consistency.

3. Which of the following is the correct syntax for a synchronized method in Java?

• A) public void synchronized methodName() { }


• B) synchronized public void methodName() { }
• C) public synchronized void methodName() { }
• D) synchronized returnType methodName() { }

Answer: C) public synchronized void methodName() { }

4. In Java, which block of code can be synchronized using a synchronized block?

• A) Any block of code.


• B) Only instance methods.
• C) Only static methods.
• D) Only constructors.

Answer: A) Any block of code.


5. What happens if two threads attempt to access a synchronized method on the same object at the same
time?

A) Both threads will execute the method simultaneously.

B) One thread will be blocked until the other finishes.

C) A runtime exception is thrown.

D) The behavior is unpredictable.

Answer: B) One thread will be blocked until the other finishes.

Deadlock and Race Conditions in Java

Introduction

In multithreading, deadlock and race conditions are common problems that can occur when multiple
threads access shared resources. Understanding these issues is crucial for developing robust and reliable
multithreaded applications.

Deadlock in Java

Deadlock occurs when two or more threads are blocked forever, each waiting for the other to release a
resource. It is a state where threads are stuck in a cycle of dependency.

Causes of Deadlock

Deadlock typically occurs in the following situations:

1. Mutual Exclusion: At least one resource must be held in a non-shareable mode. Only one thread can
access the resource at a time.
2. Hold and Wait: A thread holding a resource is waiting to acquire additional resources held by other
threads.
3. No Preemption: Resources cannot be forcibly taken from threads holding them.
4. Circular Wait: A set of threads is waiting for each other in a circular chain.

Example of Deadlock
Here is a simple example illustrating deadlock:

class A {

synchronized void methodA(B b) {

System.out.println("Thread 1: Holding lock on A...");

try { Thread.sleep(100); } catch (InterruptedException e) {}

System.out.println("Thread 1: Waiting for lock on B...");

b.last();

synchronized void last() {

System.out.println("In A's last method");

class B {

synchronized void methodB(A a) {

System.out.println("Thread 2: Holding lock on B...");

try { Thread.sleep(100); } catch (InterruptedException e) {}

System.out.println("Thread 2: Waiting for lock on A...");

a.last();

synchronized void last() {

System.out.println("In B's last method");

}
public class DeadlockExample {

public static void main(String[] args) {

final A a = new A();

final B b = new B();

new Thread(() -> a.methodA(b)).start();

new Thread(() -> b.methodB(a)).start();

In this example, Thread 1 locks A and waits for B, while Thread 2 locks B and waits for A, resulting in a
deadlock.

Dead lock diagram:

Race Conditions in Java

A race condition occurs when two or more threads try to change shared data at the same time. The final
state of the data depends on the order of execution, which can lead to unpredictable and incorrect results.

Example of Race Condition


class Counter {

private int count = 0;

void increment() {

count++;

int getCount() {

return count;

public class RaceConditionExample {

public static void main(String[] args) throws InterruptedException {

Counter counter = new Counter();

Runnable task = () -> {

for (int i = 0; i < 1000; i++) {

counter.increment();

};

Thread t1 = new Thread(task);

Thread t2 = new Thread(task);

t1.start();

t2.start();

t1.join();

t2.join();

System.out.println("Final Count: " + counter.getCount());

}
}

In this example, Counter class is accessed by multiple threads without synchronization, leading to a race
condition. The count variable might not always reflect the expected result due to concurrent
modifications.

Race Condition

Prevention Techniques

Avoiding Deadlock

1. Avoid Nested Locks: Minimize the number of locks and avoid acquiring multiple locks if possible.
2. Lock Ordering: Ensure that locks are acquired in a consistent order across threads.
3. Timeouts: Use timeouts when trying to acquire locks to avoid waiting indefinitely.
4. Deadlock Detection: Implement algorithms to detect deadlock situations and handle them gracefully.

Example of Deadlock Avoidance Using Lock Ordering:

class A {

synchronized void methodA(B b) {

System.out.println("Thread 1: Holding lock on A...");

b.last(); // Locking in a fixed order

synchronized void last() {


System.out.println("Thread 1: Executing last method");

class B {

synchronized void methodB(A a) {

System.out.println("Thread 2: Holding lock on B...");

a.last(); // Locking in a fixed order

synchronized void last() {

System.out.println("Thread 2: Executing last method");

Avoiding Race Conditions

1. Synchronization: Use synchronized blocks or methods to control access to shared resources.


2. Atomic Variables: Use atomic variables from java.util.concurrent.atomic package to ensure atomicity.
3. Locks: Use explicit locks (ReentrantLock) for more fine-grained control over synchronization.

Example of Race Condition Avoidance Using Synchronization:

class Counter {

private int count = 0;

synchronized void increment() {

count++;

}
int getCount() {

return count;

In this example, the increment() method is synchronized to prevent race conditions by ensuring that only
one thread can execute it at a time.

Do It Yourself

1. Write a Java program that simulates a deadlock situation. Implement a mechanism to detect and recover
from the deadlock.
2. Modify the Counter example to use synchronization to prevent the race condition. Verify that the final
count is always correct.
3. Create a Java program demonstrating deadlock avoidance by enforcing lock ordering.
4. Write a program that uses AtomicInteger to handle increments safely without synchronization.
5. mplement a timeout mechanism to prevent deadlocks in a multi-threaded program.

Quiz

1. What is a deadlock in multithreading?


o A) A condition where threads are executing simultaneously.
o B) A state where threads are stuck waiting for each other indefinitely.
o C) A situation where threads run faster.
o D) A state where threads execute in sequence.

Answer: B) A state where threads are stuck waiting for each other indefinitely.

2. Which of the following can cause a race condition?


o A) Synchronizing all methods.
o B) Accessing shared resources without synchronization.
o C) Using AtomicInteger for counters.
o D) Implementing thread-safe collections.

Answer: B) Accessing shared resources without synchronization.

3. Which technique is used to avoid deadlock?


o A) Ignoring the order of lock acquisition.
o B) Using a single lock for all resources.
o C) Enforcing a consistent lock ordering.
o D) Allowing infinite wait time.

Answer: C) Enforcing a consistent lock ordering.

4. What is a common symptom of a race condition?


o A) The application crashes immediately.
o B) Data is corrupted due to simultaneous modifications.
o C) Threads execute faster than expected.
o D) Threads run in a specific order.

Answer: B) Data is corrupted due to simultaneous modifications.

5. Which class in Java provides thread-safe operations for shared counters?


o A) Counter
o B) Vector
o C) AtomicInteger
o D) LinkedList

Answer: C) AtomicInteger

2. Inter-thread Communication

Inter-thread Communication in Java

Inter-thread communication in Java is a crucial concept for developing multithreaded applications. It


allows threads to communicate with each other and coordinate their actions to achieve synchronization
and data sharing.

Introduction
In multithreaded programs, threads often need to cooperate with each other, and inter-thread
communication is the mechanism that enables this cooperation. Java provides built-in methods to
facilitate communication between threads using synchronization primitives.

Key Concepts

1. Monitor: A synchronization construct that allows threads to coordinate their activities. Each object in Java
can act as a monitor.
2. Wait/Notify Mechanism: A way to manage the interaction between threads by putting threads into a
waiting state and notifying them when certain conditions are met.

Core Methods

Java provides several key methods for inter-thread communication:

1. wait(): Causes the current thread to wait until another thread invokes notify() or notifyAll() on the same
object.
2. notify(): Wakes up one of the threads that are waiting on the object’s monitor.
3. notifyAll(): Wakes up all the threads that are waiting on the object’s monitor.

Syntax

wait():

synchronized(object) {

object.wait();

notify():

synchronized(object) {

object.notify();

notifyAll():
synchronized(object) {

object.notifyAll();

Example of Inter-thread Communication

Here’s an example demonstrating inter-thread communication using wait() and notify():

class SharedResource {

private boolean isReady = false;

public synchronized void produce() {

while (isReady) {

try {

wait();

} catch (InterruptedException e) {

Thread.currentThread().interrupt();

isReady = true;

System.out.println("Produced");

notify();

public synchronized void consume() {

while (!isReady) {

try {

wait();

} catch (InterruptedException e) {
Thread.currentThread().interrupt();

isReady = false;

System.out.println("Consumed");

notify();

public class InterThreadCommunicationExample {

public static void main(String[] args) {

SharedResource resource = new SharedResource();

Thread producer = new Thread(() -> {

for (int i = 0; i < 5; i++) {

resource.produce();

});

Thread consumer = new Thread(() -> {

for (int i = 0; i < 5; i++) {

resource.consume();

});

producer.start();

consumer.start();
}

In this example, the produce() method waits if the resource is already produced and the consume()
method waits if the resource is not yet produced. The notify() method is used to signal the other thread
when the resource is ready or consumed.

Inter-thread Communication

Do It Yourself

1. Explain how wait() and notify() work in Java. Illustrate with a simple example.
2. Implement a program that demonstrates the use of notifyAll() to wake up multiple threads.
3. What are the key differences between wait() and sleep()? Provide examples where each would be
appropriately used.
4. Write a program that uses inter-thread communication to solve the producer-consumer problem.
5. Discuss the importance of synchronization when using wait() and notify(). What happens if the
synchronization is not used correctly?
Quiz

Multiple Choice Questions (MCQs)

1. What is the purpose of the wait() method in Java?

A) To pause the current thread for a specified time.

B) To notify other threads waiting on the same object.

C) To release the lock on an object and make the current thread wait.

D) To start a new thread.

Answer: C) To release the lock on an object and make the current thread wait.

2. Which method wakes up one of the threads waiting on the object's monitor?

A) notifyAll()

B) resume()

C) notify()

D) wait()

Answer: C) notify()

3. What will happen if notify() is called without any thread waiting on the object's monitor?

A) It will throw an exception.

B) It will have no effect.

C) It will immediately terminate the program.

D) It will put the current thread to sleep.

Answer: B) It will have no effect.

4. Which of the following methods should be called from within a synchronized block?

A) wait()

B) notifyAll()

C) sleep()
D) Both A and B

Answer: D) Both A and B

5. In the context of inter-thread communication, what does notifyAll() do?

A) It wakes up a single thread waiting on the object.

B) It wakes up all threads waiting on the object.

C) It pauses all threads in the system.

D) It terminates all threads in the system.

Answer: B) It wakes up all threads waiting on the object.

3. Suspending, Resuming, and Stopping of Threads

Suspended, Resumed, and Stopped Threads

Introduction

In Java, threads are the smallest units of execution within a process. They allow multiple tasks to run
concurrently. Managing the lifecycle of threads—suspending, resuming, and stopping them—can be
crucial in multi-threaded applications. This document provides a comprehensive guide to these concepts,
including explanations, examples, and practice problems.

1. Suspending Threads

Explanation:

In Java, a thread can be temporarily suspended using the suspend() method. However, it's important to
note that this method is deprecated due to potential issues like deadlocks and other synchronization
problems. Instead of suspend(), it's recommended to use other mechanisms like wait() and notify() for
thread communication and control.
Syntax:

Thread.suspend();

Example:

class MyThread extends Thread {

public void run() {

for (int i = 0; i < 10; i++) {

System.out.println("Running: " + i);

try {

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

public class TestSuspend {

public static void main(String[] args) throws InterruptedException {

MyThread t = new MyThread();

t.start();

Thread.sleep(2000); // Let the thread run for a bit

t.suspend(); // Suspend the thread

System.out.println("Thread suspended");

Thread.sleep(2000); // Wait for some time before resuming

t.resume(); // Resume the thread

System.out.println("Thread resumed");
}

2. Resuming Threads

Explanation:

A suspended thread can be resumed using the resume() method. Like suspend(), resume() is also
deprecated. It’s better to use wait() and notify() mechanisms to control thread execution.

Syntax:

Thread.resume();

Example:

// Same as the previous example, use resume() to continue execution.

3. Stopping Threads

Explanation:

To stop a thread, you should use the stop() method. However, this method is deprecated because it can
leave shared resources in an inconsistent state. Instead, use a flag to signal the thread to stop.

Syntax:

Thread.stop();

Example:

class StoppableThread extends Thread {

private volatile boolean running = true;

public void run() {

while (running) {

System.out.println("Thread running");

try {

Thread.sleep(500);
} catch (InterruptedException e) {

e.printStackTrace();

System.out.println("Thread stopped");

public void stopThread() {

running = false;

public class TestStop {

public static void main(String[] args) throws InterruptedException {

StoppableThread t = new StoppableThread();

t.start();

Thread.sleep(2000); // Let the thread run for a bit

t.stopThread(); // Stop the thread using a flag

Practice Problem

Problem:

Create a Java program with three threads:

1. SuspensionThread - This thread prints numbers from 1 to 10, and after printing 5 numbers, it should be
suspended and then resumed.
2. ResumingThread - This thread should print a message every 1 second, and it should be stopped after 5
seconds.
3. StoppingThread - This thread should run indefinitely until a stop flag is set, then it should stop gracefully.
Code:

class SuspensionThread extends Thread {

private boolean suspended = false;

public synchronized void run() {

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

while (suspended) {

try {

wait();

} catch (InterruptedException e) {

e.printStackTrace();

System.out.println("SuspensionThread: " + i);

try {

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

if (i == 5) {

suspendThread();

public synchronized void suspendThread() {

suspended = true;
}

public synchronized void resumeThread() {

suspended = false;

notify();

class ResumingThread extends Thread {

public void run() {

long startTime = System.currentTimeMillis();

while (System.currentTimeMillis() - startTime < 5000) {

System.out.println("ResumingThread is running");

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

System.out.println("ResumingThread stopped");

class StoppingThread extends Thread {

private volatile boolean running = true;

public void run() {


while (running) {

System.out.println("StoppingThread running");

try {

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

System.out.println("StoppingThread stopped");

public void stopThread() {

running = false;

public class ThreadManagement {

public static void main(String[] args) throws InterruptedException {

SuspensionThread t1 = new SuspensionThread();

ResumingThread t2 = new ResumingThread();

StoppingThread t3 = new StoppingThread();

t1.start();

t2.start();

t3.start();

Thread.sleep(2000);

t1.resumeThread();
Thread.sleep(3000);

t3.stopThread();

Do It Yourself

1. Explain why the suspend() and resume() methods are deprecated. What are the recommended alternatives?
2. Write a Java program using wait() and notify() to demonstrate thread suspension and resumption.
3. Modify the StoppingThread example to use the stop() method and discuss the issues encountered.
4. How can you safely stop a thread without using deprecated methods? Write a sample code to illustrate this.
5. Discuss the impact of thread suspension and resumption on thread safety and synchronization.

Quiz

1. Which method is used to pause a thread's execution temporarily?

• a) stop()
• b) suspend()
• c) wait()
• d) sleep()

Answer: b) suspend()

2. Which method can be used to resume a suspended thread?

• a) resume()
• b) notify()
• c) start()
• d) continue()

Answer: a) resume()
3. What is a safer alternative to the deprecated stop() method for stopping a thread?

• a) Using Thread.stop()
• b) Using a boolean flag and checking it regularly
• c) Using Thread.interrupt()
• d) Using Thread.suspend()

Answer: b) Using a boolean flag and checking it regularly

4. Which method should be used to notify a waiting thread?

• a) notifyAll()
• b) interrupt()
• c) notify()
• d) resume()

Answer: c) notify()

5. Consider the following code snippet:

Thread t = new Thread(() -> {

while (true) {

// Do something

});

t.start();

t.stop();

What is the main issue with using t.stop() in this code?**

a) The thread will stop immediately, potentially leaving resources in an inconsistent state.

b) The thread will be suspended and cannot be resumed.

c) The thread will cause a deadlock.

d) The code will not compile.

Answer: a) The thread will stop immediately, potentially leaving resources in an inconsistent state.
Introduction to JDBC (Java Database Connectivity)
Introduction

Java Database Connectivity (JDBC) is an API that allows Java applications to interact with databases. It
provides a standard interface for connecting to various databases, executing SQL queries, and managing
results. JDBC is essential for enterprise applications that require interaction with relational databases.

Definition of JDBC:

JDBC stands for Java Database Connectivity. It is a Java API used to connect and execute queries with
databases. JDBC is a specification from Sun Microsystems that provides a standard abstraction (API or
Protocol) for Java applications to communicate with various databases. It enables Java applications to
access and manipulate databases and spreadsheets, particularly relational databases (RDBs).

Current Version:

The current version of JDBC is JDBC 4.3, released on September 21, 2017.

Purpose of JDBC:

JDBC is crucial for enterprise applications created using Java EE technology. It provides efficient
database connectivity by enabling Java applications to interact with various databases, such as Oracle,
MS Access, MySQL, and SQL Server. JDBC, combined with database drivers, allows access to and
manipulation of data stored in relational databases.

1. JDBC Components

1. JDBC API

JDBC API provides methods and interfaces for communication with the database. It consists of two
packages:

• java.sql: Contains classes and interfaces for data access and processing in a relational database. Included in
Java Standard Edition (Java SE).
• javax.sql: Extends the functionality of java.sql by providing data source interfaces for connection pooling
and statement pooling. Included in Java Enterprise Edition (Java EE).

2. JDBC Driver Manager

The DriverManager class loads database-specific drivers and establishes connections to databases. It
manages a list of database drivers and makes calls to process user requests.

3. JDBC Test Suite

The JDBC Test Suite is used to test operations performed by JDBC drivers, such as insertion, deletion,
and updates.

4. JDBC-ODBC Bridge Drivers

JDBC-ODBC Bridge Drivers connect database drivers to databases. They translate JDBC method calls
into ODBC function calls and use the sun.jdbc.odbc package, which includes a native library to access
ODBC characteristics.

2. JDBC Drivers

Explanation:

JDBC drivers implement the JDBC API to connect Java applications to databases. There are four types
of JDBC drivers:

1. Type 1: JDBC-ODBC Bridge Driver - Uses ODBC drivers to connect to the database.
2. Type 2: Native-API Driver - Converts JDBC calls into database-specific calls using native libraries.
3. Type 3: Network Protocol Driver - Converts JDBC calls into a database-independent network protocol,
which is then translated into database-specific calls.
4. Type 4: Thin Driver - Converts JDBC calls directly into database-specific calls.

Example:

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

public class JdbcExample {


public static void main(String[] args) {

String url = "jdbc:mysql://localhost:3306/mydatabase";

String user = "root";

String password = "password";

try {

Connection connection = DriverManager.getConnection(url, user, password);

System.out.println("Connection established!");

} catch (SQLException e) {

e.printStackTrace();

JDBC Architecture: A Comprehensive Guide

1. Overview of JDBC Architecture

Java Database Connectivity (JDBC) is an API that allows Java applications to interact with databases. It
provides a standard interface for connecting to various databases and executing SQL queries.

2. Components of JDBC Architecture

Application:

Description: A Java application (could be a Java applet or a servlet) that communicates with a data
source.

JDBC API:

Purpose: Provides methods to execute SQL statements and retrieve results from a database.
Important Interfaces:

• Driver: Manages the connection to the database.


• Connection: Establishes and manages a connection to the database.
• Statement: Used to execute SQL queries.
• PreparedStatement: A Statement subclass for precompiled SQL queries.
• CallableStatement: Executes stored procedures.
• ResultSet: Represents the result set of a query.
• RowSet: Represents a set of rows.
• ResultSetMetaData: Provides information about the result set.
• DatabaseMetaData: Provides information about the database.

Important Classes:

• DriverManager: Manages a list of database drivers.


• Types: Defines constants for SQL data types.
• Blob: Handles Binary Large Objects.
• Clob: Handles Character Large Objects.

DriverManager:

Role: Manages a list of database drivers and establishes a connection between the Java application and
the database.

JDBC Drivers:

Purpose: Translate Java calls into database-specific calls. There are four types:

• Type-1: JDBC-ODBC Bridge Driver


• Type-2: Native-API Driver
• Type-3: Network Protocol Driver
• Type-4: Thin Driver
3. Types of JDBC Architecture

Two-Tier Model:
Description: Direct communication between the Java application and the database. The JDBC driver
enables this communication.

Example: A Java application on a client machine communicates directly with a database server.

Three-Tier Model:

Description: The application communicates with a middle tier (application server) that then
communicates with the database.

Example: A web application communicates with a middleware server, which then accesses the database.

4. What is an API?

API (Application Programming Interface):

Description: A set of rules and protocols for building and interacting with software applications. It allows
different software systems to communicate with each other without needing to understand each other's
code.

5. Working of JDBC

A JDBC application follows these steps:


1. Load Driver: Load the JDBC driver using Class.forName().
2. Establish Connection: Obtain a Connection object using DriverManager.getConnection().
3. Create Statement: Create a Statement or PreparedStatement object.
4. Execute Query: Execute SQL queries using the statement object.
5. Process Results: Process the results using ResultSet.
6. Close Connection: Close the connection when done.

6. Example: Simple JDBC Application

package com.example.jdbc;

import java.sql.*;

public class JDBCDemo {

public static void main(String[] args) {

String driverClassName = "com.mysql.cj.jdbc.Driver";

String url = "jdbc:mysql://localhost:3306/mydatabase";

String username = "root";

String password = "password";

String query = "INSERT INTO students (id, name) VALUES (110, 'Smith')";

try {

// Load the JDBC driver

Class.forName(driverClassName);

// Establish a connection

Connection con = DriverManager.getConnection(url, username, password);

// Create a statement

Statement st = con.createStatement();
// Execute the query

int count = st.executeUpdate(query);

System.out.println("Number of rows affected: " + count);

// Close the connection

con.close();

} catch (SQLException | ClassNotFoundException e) {

e.printStackTrace();

Explanation:

This example demonstrates how to use JDBC to insert data into a database. The DriverManager is used
to manage the connection, and the Statement is used to execute the SQL query.

Do It Yourself

1. Explain the role of DriverManager in JDBC.


2. What is the difference between Statement and PreparedStatement? Provide an example of when to use each.
3. Describe the two-tier and three-tier JDBC architecture models with examples.
4. How does a JDBC driver work? Explain the four types of JDBC drivers.
5. Write a JDBC program to retrieve data from a table named employees with columns id, name, and
department.

Quiz
1. Which JDBC driver type is also known as the "Thin Driver"?

• A. Type-1
• B. Type-2
• C. Type-3
• D. Type-4

Answer: D. Type-4

2. Which interface is used to execute SQL queries in JDBC?

• A. Driver
• B. Connection
• C. Statement
• D. ResultSet

Answer: C. Statement

3. What method is used to load a JDBC driver class?

• A. DriverManager.loadDriver()
• B. Class.forName()
• C. DriverManager.getConnection()
• D. Connection.createStatement()

Answer: B. Class.forName()

4. Which JDBC interface provides information about the result set?

• A. Driver
• B. ResultSet
• C. Statement
• D. Connection

Answer: B. ResultSet
5. Consider the following code snippet:

Connection con = DriverManager.getConnection(url, username, password);

Statement stmt = con.createStatement();

ResultSet rs = stmt.executeQuery("SELECT * FROM employees");

while (rs.next()) {

System.out.println(rs.getInt("id") + " " + rs.getString("name"));

What will this code do?

• A. Insert data into the employees table


• B. Update data in the employees table
• C. Retrieve and display all data from the employees table
• D. Delete data from the employees table

Answer: C. Retrieve and display all data from the employees table

3. Installing MySQL and MySQL Connector/J

Installing MySQL and MySQL Connector/J

This guide will walk you through the process of installing MySQL and MySQL Connector/J, which is
essential for connecting Java applications to MySQL databases.

1. Installing MySQL

Step 1: Download MySQL Installer

1. Go to the MySQL Downloads page.


2. Choose the appropriate version of the MySQL Installer for your operating system (Windows, macOS,
Linux).
Step 2: Run the Installer

1. Open the downloaded installer file.


2. Choose the setup type. For most users, the "Developer Default" option is recommended. It installs MySQL
Server and other useful tools like MySQL Workbench and MySQL Shell.

Step 3: Follow Installation Wizard

1. Setup Type: Choose "Developer Default" or "Server only" based on your needs.
2. Check Requirements: The installer will check for any missing dependencies and guide you through
installing them if necessary.
3. Configuration: Set up MySQL Server:
• Authentication Method: Choose either the default or use the "Use Strong Password Encryption"
option.
• Account Setup: Set up the root user password and create additional user accounts if needed.
• Server Configuration: Configure settings like port number (default is 3306) and character set.
4. Complete Installation: Click "Execute" to begin the installation. Once completed, the installer will provide
options to start MySQL Server and configure MySQL Workbench.

Step 4: Verify Installation

1. Open MySQL Workbench or a terminal/command prompt.


2. Connect to the MySQL Server using the credentials set during installation.
3. Run a simple query to verify everything is working:

SELECT VERSION();

2. Installing MySQL Connector/J

Step 1: Download MySQL Connector/J

1. Visit the MySQL Connector/J Downloads page.


2. Choose the version compatible with your MySQL Server and download the .zip or .tar.gz file.

Step 2: Extract the Archive

1. Extract the downloaded archive to a directory on your system.


Step 3: Add Connector/J to Your Java Project

1. IDE Integration:

• Eclipse:
• Right-click your project in the Project Explorer.
• Select Properties > Java Build Path > Libraries > Add External JARs.
• Navigate to the extracted Connector/J directory and select mysql-connector-java-x.x.x-bin.jar.
• IntelliJ IDEA:
• Right-click on your project and select Open Module Settings.
• Go to Libraries and click + to add the JAR file.

2. Manual Configuration:

• If you are not using an IDE, add the mysql-connector-java-x.x.x-bin.jar file to your classpath manually.

3. Connecting Java to MySQL

Example Code:

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Statement;

public class MySQLConnectionDemo {

public static void main(String[] args) {

String url = "jdbc:mysql://localhost:3306/mydatabase";

String username = "root";

String password = "password";

try {

// Load the JDBC driver

Class.forName("com.mysql.cj.jdbc.Driver");
// Establish the connection

Connection con = DriverManager.getConnection(url, username, password);

// Create a statement

Statement stmt = con.createStatement();

// Execute a query

String query = "CREATE TABLE test (id INT PRIMARY KEY, name VARCHAR(50))";

stmt.executeUpdate(query);

System.out.println("Table created successfully.");

// Close the connection

con.close();

} catch (ClassNotFoundException | SQLException e) {

e.printStackTrace();

Explanation:

Driver Loading: Class.forName("com.mysql.cj.jdbc.Driver") loads the MySQL JDBC driver.

• Connection Establishment: DriverManager.getConnection(url, username, password) establishes a


connection to the MySQL server.
• Query Execution: stmt.executeUpdate(query) runs a SQL query to create a table.
Quiz

1. Which of the following is the correct URL format for connecting to a MySQL database?

• A. jdbc:mysql://localhost:3306/mydatabase
• B. jdbc:oracle:localhost:3306/mydatabase
• C. jdbc:sqlserver://localhost:3306/mydatabase
• D. jdbc:postgresql://localhost:3306/mydatabase

Answer: A. jdbc:mysql://localhost:3306/mydatabase

2. What is the default port number for MySQL Server?

• A. 1433
• B. 1521
• C. 3306
• D. 5432

Answer: C. 3306

3. Which class is used to establish a connection to a MySQL database?

• A. Statement
• B. DriverManager
• C. Connection
• D. ResultSet

Answer: B. DriverManager

4. What does the following line of code do? Class.forName("com.mysql.cj.jdbc.Driver");

• A. Creates a new MySQL database


• B. Loads the MySQL JDBC driver
• C. Executes a SQL query
• D. Establishes a database connection

Answer: B. Loads the MySQL JDBC driver


5. What is the purpose of the mysql-connector-java-x.x.x-bin.jar file?

• A. It contains the MySQL Server executable


• B. It provides the MySQL command-line client
• C. It contains the JDBC driver for connecting Java applications to MySQL
• D. It provides a graphical interface for MySQL management

Answer: C. It contains the JDBC driver for connecting Java applications to MySQL

4. JDBC Environment Setup

JDBC Environment Setup

Setting up a JDBC (Java Database Connectivity) environment involves several steps to ensure that your
Java application can interact with a database. This guide provides detailed instructions for setting up the
JDBC environment, including installation, configuration, and basic usage.

1. Installing Java Development Kit (JDK)

Step 1: Download JDK

Visit the Oracle JDK Downloads page or the AdoptOpenJDK page.

1. Choose the appropriate version of the JDK for your operating system (Windows, macOS, Linux).
2. Download and install the JDK by following the provided instructions.

Step 2: Verify Installation

1. Open a command prompt or terminal.


2. Run the command:

java -version

You should see the version information for the JDK.

2. Installing MySQL Database

Step 1: Download MySQL Installer

1. Go to the MySQL Downloads page.


2. Choose the appropriate version of the MySQL Installer for your operating system (Windows, macOS,
Linux).

Step 2: Run the Installer

1. Open the downloaded installer file.


2. Choose the setup type. For most users, the "Developer Default" option is recommended.
3. Follow the installation wizard to install MySQL Server, MySQL Workbench, and other tools.

Step 3: Verify Installation

1. Open MySQL Workbench or a terminal.


2. Connect to the MySQL Server using the credentials set during installation.
3. Run a simple query to verify everything is working:

SELECT VERSION();

3. Downloading and Adding MySQL Connector/J

Step 1: Download MySQL Connector/J

1. Visit the MySQL Connector/J Downloads page.


2. Download the .zip or .tar.gz file for the Connector/J version compatible with your MySQL Server.

Step 2: Extract the Archive

1. Extract the downloaded file to a directory on your system.


Step 3: Add Connector/J to Your Java Project

1. IDE Integration:

• Eclipse:
• Right-click your project in the Project Explorer.
• Select Properties > Java Build Path > Libraries > Add External JARs.
• Navigate to the extracted Connector/J directory and select mysql-connector-java-x.x.x-bin.jar.
• IntelliJ IDEA:
• Right-click on your project and select Open Module Settings.
• Go to Libraries and click + to add the JAR file.

2. Manual Configuration:

• If you are not using an IDE, add the mysql-connector-java-x.x.x-bin.jar file to your classpath manually.

4. Setting Up JDBC Environment

Step 1: Load the JDBC Driver

In your Java application, you need to load the JDBC driver class. For MySQL Connector/J, this can be
done using Class.forName():

Class.forName("com.mysql.cj.jdbc.Driver");

Step 2: Establish a Database Connection

Use the DriverManager.getConnection() method to connect to the MySQL database:

String url = "jdbc:mysql://localhost:3306/mydatabase";

String username = "root";

String password = "password";

Connection con = DriverManager.getConnection(url, username, password);

Step 3: Create and Execute Statements

Once connected, you can create Statement or PreparedStatement objects to execute SQL queries:
Statement stmt = con.createStatement();

ResultSet rs = stmt.executeQuery("SELECT * FROM employees");

Step 4: Process Results

Process the ResultSet to retrieve and display query results:

while (rs.next()) {

System.out.println(rs.getInt("id") + " " + rs.getString("name"));

Step 5: Close the Connection

Finally, close the connection and other resources:

rs.close();

stmt.close();

con.close();

Example Code:

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

public class JDBCExample {

public static void main(String[] args) {

String url = "jdbc:mysql://localhost:3306/mydatabase";

String username = "root";

String password = "password";


try {

// Load the JDBC driver

Class.forName("com.mysql.cj.jdbc.Driver");

// Establish a connection

Connection con = DriverManager.getConnection(url, username, password);

// Create a statement

Statement stmt = con.createStatement();

// Execute a query

ResultSet rs = stmt.executeQuery("SELECT * FROM employees");

// Process the results

while (rs.next()) {

System.out.println(rs.getInt("id") + " " + rs.getString("name"));

// Close resources

rs.close();

stmt.close();

con.close();

} catch (ClassNotFoundException | SQLException e) {

e.printStackTrace();

Explanation:

• Driver Loading: Class.forName("com.mysql.cj.jdbc.Driver") loads the MySQL JDBC driver class.


• Connection Establishment: DriverManager.getConnection(url, username, password) connects to the
MySQL database using provided credentials.
• Query Execution: stmt.executeQuery("SELECT * FROM employees") retrieves data from the employees
table.
• Resource Management: Always close ResultSet, Statement, and Connection to free resources.

Do It Yourself

1. Explain the steps involved in installing the JDK and verifying its installation.
2. Describe the process of downloading and adding MySQL Connector/J to a Java project using Eclipse.
3. Write a JDBC program to connect to a MySQL database and create a table named students with columns id
and name.
4. How do you load the JDBC driver for MySQL in a Java application?
5. What is the purpose of DriverManager.getConnection() method in JDBC?

Quiz

1. What is the purpose of Class.forName("com.mysql.cj.jdbc.Driver") in a JDBC application?

• A. To establish a connection to the database


• B. To load the JDBC driver class
• C. To execute a SQL query
• D. To create a database table

Answer: B. To load the JDBC driver class

2. Which method is used to establish a connection to a MySQL database in JDBC?

• A. DriverManager.getConnection()
• B. Statement.execute()
• C. ResultSet.getString()
• D. Class.forName()
Answer: A. DriverManager.getConnection()

3. What is the default port number for MySQL Server?

• A. 1433
• B. 3306
• C. 1521
• D. 5432

Answer: B. 3306

4. Which class provides methods to execute SQL queries in JDBC?

• A. Connection
• B. ResultSet
• C. Statement
• D. DriverManager

Answer: C. Statement

5. Consider the following code snippet:

Connection con = DriverManager.getConnection(url, username, password);

Statement stmt = con.createStatement();

ResultSet rs = stmt.executeQuery("SELECT * FROM employees");

while (rs.next()) {

System.out.println(rs.getInt("id") + " " + rs.getString("name"));

What does this code do?

• A. Inserts data into the employees table


• B. Updates records in the employees table
• C. Retrieves and displays all records from the employees table
• D. Deletes records from the employees table

Answer: C. Retrieves and displays all records from the employees table
Establishing JDBC Database Connections

Establishing a JDBC (Java Database Connectivity) connection is a fundamental step in interacting with a
database using Java. This guide covers the steps and key concepts involved in setting up and managing
JDBC connections.

1. Overview of JDBC Connection

To interact with a database using JDBC, you need to follow these essential steps:

1. Load the JDBC Driver: This step involves loading the JDBC driver class that facilitates communication
between Java and the database.
2. Establish a Connection: Use the DriverManager class to create a connection to the database.
3. Create a Statement: Create a Statement, PreparedStatement, or CallableStatement object to execute SQL
queries.
4. Execute Queries: Run SQL queries using the statement object.
5. Process Results: Retrieve and process the results of the queries.
6. Close Resources: Properly close the ResultSet, Statement, and Connection to free up resources.

Example JDBC Workflow:

1. Load JDBC Driver


2. Connect to Database
3. Create SQL Statement
4. Execute Query
5. Process Results
6. Close Connection

2. Loading the JDBC Driver

Syntax:

Class.forName("com.mysql.cj.jdbc.Driver");

Explanation:

• Class.forName("com.mysql.cj.jdbc.Driver") loads the MySQL JDBC driver class into memory, which is
required to establish a connection to the database.

\
3. Establishing a Connection

Syntax:

String url = "jdbc:mysql://localhost:3306/mydatabase";

String username = "root";

String password = "password";

Connection con = DriverManager.getConnection(url, username, password);

Explanation:

url: The URL of the database to connect to. It includes the protocol (jdbc:mysql), the host (localhost), the
port (3306), and the database name (mydatabase).

username: The username for database authentication.

password: The password for database authentication.

DriverManager.getConnection(url, username, password): This method establishes a connection to the


database using the provided credentials.

4. Creating and Executing Statements

Syntax:

Statement stmt = con.createStatement();

ResultSet rs = stmt.executeQuery("SELECT * FROM employees");

Explanation:

• Statement: Creates a Statement object for sending SQL statements to the database.
• executeQuery(): Executes a SQL query and returns the result in a ResultSet object.
5. Processing Results

Syntax:

while (rs.next()) {

System.out.println(rs.getInt("id") + " " + rs.getString("name"));

Explanation:

• ResultSet: Represents the result set of a query. The next() method moves the cursor to the next row.
• getInt("id"): Retrieves the value of the id column.
• getString("name"): Retrieves the value of the name column.

6. Closing Resources

Syntax:

rs.close();

stmt.close();

con.close();

Explanation:

• close(): Closes the ResultSet, Statement, and Connection to free up database resources.

7. Practice Programs

1. Basic JDBC Connection: Write a Java program to connect to a MySQL database and print the current
date using SELECT NOW();.

2. Insert Data: Write a Java program to connect to a MySQL database and insert a new record into a table
named students with columns id and name.

3.Update Data: Write a Java program to connect to a MySQL database and update the name of a student
with a specific id in the students table.
4. Delete Data: Write a Java program to connect to a MySQL database and delete a record from the students
table based on a specific id.

5. Retrieve Data: Write a Java program to connect to a MySQL database, retrieve all records from the
students table, and print them.

Do It Yourself

1. Explain the purpose of loading the JDBC driver class in a JDBC application.
2. How do you establish a connection to a MySQL database using JDBC? Provide a code example.
3. Write a JDBC program to create a table named employees with columns id, name, and salary.
4. What are the steps to execute a SQL query using JDBC and process the results?
5. Why is it important to close JDBC resources like ResultSet, Statement, and Connection?

Quiz

1. Which method is used to load the JDBC driver class in a Java application?

• A. DriverManager.getConnection()
• B. Class.forName()
• C. Statement.executeQuery()
• D. ResultSet.next()

Answer: B. Class.forName()

2. What does the DriverManager.getConnection(url, username, password) method do?

• A. Loads the JDBC driver class


• B. Executes a SQL query
• C. Establishes a connection to the database
• D. Retrieves the result of a query
Answer: C. Establishes a connection to the database

3. Which JDBC object is used to execute SQL queries and update statements?

• A. Connection
• B. ResultSet
• C. Statement
• D. DriverManager

Answer: C. Statement

4. What does the ResultSet.next() method do?

• A. Executes a SQL query


• B. Moves the cursor to the next row in the result set
• C. Closes the result set
• D. Retrieves the value of a column

Answer: B. Moves the cursor to the next row in the result set

5. Which of the following is true about closing JDBC resources?

• A. It is optional and not necessary


• B. It prevents memory leaks and resource wastage
• C. It is done automatically by JDBC
• D. It is done only for Statement objects

Answer: B. It prevents memory leaks and resource wastage

2. Working with ResultSet Interface

Working with ResultSet Interface

The ResultSet interface in JDBC is used to handle the result set of a query executed against a database. It
allows you to retrieve and manipulate the data returned by a SQL query. This guide covers the essential
aspects of working with the ResultSet interface, including its methods, usage, and best practices.
1. Overview of ResultSet Interface

The ResultSet interface represents a table of data resulting from a query. It provides methods to iterate
through the rows and retrieve data from columns. The ResultSet is automatically created by executing a
SQL query using a Statement or PreparedStatement object.

Key Points:

• Read-Only: By default, a ResultSet is read-only.


• Forward-Only: The default type of a ResultSet object is forward-only, meaning you can only move
forward through the data.

2. Creating a ResultSet

Syntax:

Statement stmt = con.createStatement();

ResultSet rs = stmt.executeQuery("SELECT * FROM employees");

Explanation:

Statement.createStatement(): Creates a Statement object for sending SQL statements to the database.

Statement.executeQuery(): Executes the SQL query and returns a ResultSet object.

3. Navigating Through ResultSet

Key Methods:

• next(): Moves the cursor to the next row of the ResultSet.

while (rs.next()) {

// Process the current row

• previous(): Moves the cursor to the previous row (if the ResultSet type is scrollable).

rs.previous();

• first(): Moves the cursor to the first row (if the ResultSet type is scrollable).
rs.first();

• last(): Moves the cursor to the last row (if the ResultSet type is scrollable).

rs.last();

4. Retrieving Data from ResultSet

Key Methods:

• getString(String columnLabel): Retrieves the value of the specified column as a String.

String name = rs.getString("name");

• getInt(String columnLabel): Retrieves the value of the specified column as an int.

int id = rs.getInt("id");

• getDouble(String columnLabel): Retrieves the value of the specified column as a double.

double salary = rs.getDouble("salary");

• getDate(String columnLabel): Retrieves the value of the specified column as a Date.

Date hireDate = rs.getDate("hire_date");

5. Handling Different Data Types

• getBoolean(String columnLabel): Retrieves the value of the specified column as a boolean.


• getFloat(String columnLabel): Retrieves the value of the specified column as a float.
• getLong(String columnLabel): Retrieves the value of the specified column as a long.
• getObject(String columnLabel): Retrieves the value of the specified column as an Object.

Example:

boolean isActive = rs.getBoolean("is_active");

float height = rs.getFloat("height");

long employeeId = rs.getLong("employee_id");

Object department = rs.getObject("department");


6. Best Practices

• Always Check for Valid Data: Use ResultSet methods carefully to avoid SQLException and ensure proper
handling of null values.
• Close ResultSet and Other Resources: Always close ResultSet, Statement, and Connection to prevent
resource leaks.
• Use Column Indexes for Efficiency: In cases where column labels might be subject to change, use column
indexes to access data.

Example of Closing Resources:

rs.close();

stmt.close();

con.close();

7. Practice Programs

1. Retrieve All Records: Write a Java program to connect to a MySQL database, retrieve all records from a
table named employees, and print each record's id, name, and salary.

2. Process Specific Column Data: Write a Java program to connect to a MySQL database, retrieve and print
the names of all employees who have a salary greater than a specific amount.

3. Retrieve Data Based on Date: Write a Java program to connect to a MySQL database, retrieve all
employees who were hired after a specific date, and display their names and hire dates.

4. Handle Null Values: Write a Java program to handle potential null values when retrieving data from a
ResultSet, and ensure your code does not throw exceptions when encountering nulls.

5. Pagination Example: Write a Java program to fetch a subset of records from the employees table,
implementing pagination to retrieve records in chunks (e.g., 10 records per page).

Do It Yourself

1. Explain the purpose of the ResultSet interface in JDBC.


2. How do you retrieve an integer value from a ResultSet? Provide a code example.
3. Write a JDBC program to navigate through a ResultSet and print all employee names from the employees
table.
4. What are the methods available to navigate through a ResultSet? Explain with examples.
5. Why is it important to close the ResultSet and other JDBC resources?

Quiz

1. Which method is used to move the cursor to the next row in a ResultSet?

• A. previous()
• B. first()
• C. next()
• D. last()

Answer: C. next()

2. How can you retrieve a String value from a ResultSet?

• A. rs.getString("columnName")
• B. rs.getInt("columnName")
• C. rs.getDouble("columnName")
• D. rs.getObject("columnName")

Answer: A. rs.getString("columnName")

3. Which method would you use to check if there are more rows in a ResultSet?

• A. rs.isLast()
• B. rs.next()
• C. rs.previous()
• D. rs.first()

Answer: B. rs.next()
4. What does the ResultSet.getObject() method do?

• A. Retrieves data as a specific type


• B. Retrieves data as a generic Object
• C. Moves the cursor to the specified row
• D. Executes a SQL update statement

Answer: B. Retrieves data as a generic Object

5. Which of the following is NOT a method of the ResultSet interface?

• A. getBoolean()
• B. getDate()
• C. getInt()
• D. getSize()

Answer: D. getSize()

JavaFX Scene Builder

JavaFX Scene Builder is a visual layout tool that allows developers to design JavaFX application user
interfaces (UIs) without writing any code. It provides a drag-and-drop interface for arranging UI
components and creating FXML (FXML is an XML-based language used to define the structure of a
JavaFX user interface). This guide will cover the basics of JavaFX Scene Builder, including its features,
syntax, and usage.

1. Overview of JavaFX Scene Builder

JavaFX Scene Builder is a graphical user interface tool used to design JavaFX applications. It enables
developers to visually build and configure user interfaces for JavaFX applications. Scene Builder
generates FXML files that can be loaded into JavaFX applications at runtime.

Key Features:
• Drag-and-Drop Interface: Allows easy placement of UI elements.
• Real-Time Preview: Provides a real-time preview of the UI as it is designed.
• Property Configuration: Enables configuration of UI component properties through an intuitive interface.
• Event Handling: Allows setting up event handlers for UI components.

2. Getting Started with JavaFX Scene Builder

1. Download and Install Scene Builder:

• Visit the Scene Builder download page to download the latest version of Scene Builder.
• Follow the installation instructions for your operating system.

2. Integrating with an IDE:

• Scene Builder can be integrated with IDEs like IntelliJ IDEA, Eclipse, or NetBeans. This integration allows
seamless opening of FXML files within the IDE.

3. Creating a JavaFX UI with Scene Builder

1. Open Scene Builder:

• Launch Scene Builder after installation.

2. Creating a New FXML File:

• Go to File > New to create a new FXML file.


• Choose a layout container, such as AnchorPane, BorderPane, or GridPane.

3. Adding UI Components:

• Drag and drop UI components (e.g., Button, Label, TextField) from the Library panel onto the design
canvas.
• Use the Inspector panel to set properties (e.g., text, size, alignment) for the selected component.

4. Setting Up Event Handlers:

• Select a UI component and go to the Code panel to set up event handlers (e.g., onAction for a
Button).Example: Creating a simple UI with a Button and Label:
• Drag a Button from the Library panel.
• Drag a Label from the Library panel.
• Use the Inspector to set the Button text to "Click Me" and the Label text to "Hello, JavaFX!".

4. Saving and Using FXML Files

1. Save the FXML File:

• Go to File > Save to save your design as an FXML file.

2. Load FXML in Java Code:

• Use FXMLLoader to load the FXML file in your JavaFX application.

Example Code:

import javafx.application.Application;

import javafx.fxml.FXMLLoader;

import javafx.scene.Parent;

import javafx.scene.Scene;

import javafx.stage.Stage;

public class MainApp extends Application {

@Override

public void start(Stage primaryStage) throws Exception {

Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));

primaryStage.setTitle("JavaFX Scene Builder Example");

primaryStage.setScene(new Scene(root, 300, 275));

primaryStage.show();

public static void main(String[] args) {

launch(args);

}
5. Practice Programs

1. Simple Form Design: Create a form with TextField, PasswordField, Button, and Label. Use Scene Builder
to design the form and set up an event handler for the button to display the entered text.

2. Calculator Layout: Design a simple calculator UI with buttons for digits (0-9), operations (+, -, *, /), and
an TextField for the display. Arrange the buttons in a grid layout.

3. Login Window: Create a login window with TextField for username, PasswordField for password, and
Button for login. Design the UI using Scene Builder and set up an action for the login button.

4. Student Registration Form: Design a registration form with fields for name, email, and phone number,
and a Button for submission. Use Scene Builder to arrange and style the components.

5. To-Do List: Create a simple to-do list application UI with a ListView for tasks and TextField for adding
new tasks. Include Button for adding tasks and removing selected tasks.

Do It Yourself

1. What is JavaFX Scene Builder, and what is its primary purpose?


2. Describe the process of creating a new FXML file using Scene Builder.
3. How do you set up event handlers for UI components in Scene Builder? Provide an example.
4. Explain how to integrate JavaFX Scene Builder with an IDE like IntelliJ IDEA or Eclipse.
5. What are the steps to load an FXML file into a JavaFX application?

Quiz

1. Which panel in Scene Builder allows you to add UI components to the design canvas?

• A. Library Panel
• B. Inspector Panel
• C. Code Panel
• D. Preview Panel
Answer: A. Library Panel

2. What file format does Scene Builder use to save user interface designs?

• A. XML
• B. JSON
• C. FXML
• D. HTML

Answer: C. FXML

3. How can you set up an event handler for a button in Scene Builder?

• A. Use the Library panel


• B. Use the Inspector panel
• C. Use the Code panel
• D. Use the Preview panel

Answer: C. Use the Code panel

4. Which method is used to load an FXML file into a JavaFX application?

• A. load()
• B. initialize()
• C. FXMLLoader.load()
• D. SceneBuilder.load()

Answer: C. FXMLLoader.load()

5. What is the primary purpose of using JavaFX Scene Builder?

• A. To compile JavaFX applications


• B. To design and layout JavaFX UIs visually
• C. To manage database connections
• D. To debug JavaFX code

Answer: B. To design and layout JavaFX UIs visually


JavaFX App Window Structure

JavaFX provides a comprehensive structure for creating graphical user interfaces (GUIs). The structure
of a typical JavaFX application window involves several core elements, including the Stage, Scene, and
Nodes. Understanding how these components interact allows developers to design well-structured and
functional applications.

1. Overview of JavaFX App Window Structure

A JavaFX window consists of the following main components:

• Stage: The main window of the JavaFX application.


• Scene: The container inside the Stage where all UI components (nodes) are placed.
• Nodes: Elements inside the scene, such as buttons, text fields, labels, layouts, etc.

2. Components of a JavaFX App Window

1. Stage: The Stage class is the top-level container. It represents the window itself. Every JavaFX application
has a primary stage that is automatically created when the application is launched.

You can set the title of the stage, its size, and its visibility.

Syntax:

Stage primaryStage = new Stage();

primaryStage.setTitle("JavaFX Application");

primaryStage.show();
2. Scene: The Scene class represents the content inside the stage. It contains all the UI components (nodes). A
Scene can hold one or more nodes arranged hierarchically.

• You can define different layouts like VBox, HBox, GridPane, etc., inside a scene.

Syntax:

VBox root = new VBox();

Scene scene = new Scene(root, 300, 200);

primaryStage.setScene(scene);

3. Nodes: Nodes are the actual UI elements like buttons, text fields, labels, etc., that are added to the scene.
Nodes are part of the Scene Graph, a hierarchical structure where parent nodes can contain child nodes.

Syntax:

Button button = new Button("Click Me");

root.getChildren().add(button);

3. Example: Creating a Simple JavaFX Window

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.control.Button;

import javafx.scene.layout.VBox;

import javafx.stage.Stage;
public class SimpleWindowApp extends Application {

@Override

public void start(Stage primaryStage) {

// Create a VBox layout

VBox root = new VBox();

// Create a button and add it to the root node

Button button = new Button("Click Me");

root.getChildren().add(button);

// Create a scene and add the layout to it

Scene scene = new Scene(root, 400, 300);

// Set the title and scene for the stage

primaryStage.setTitle("Simple JavaFX App Window");

primaryStage.setScene(scene);

// Show the stage

primaryStage.show();

public static void main(String[] args) {

launch(args);

}
Explanation:

• Stage: The main window (primaryStage) is created.


• Scene: A scene is created with a VBox layout.
• Node: A button is added to the layout.
• Show: The window is displayed with the primaryStage.show() method.

4. Layout Types in JavaFX

JavaFX provides several layout classes to organize the components inside the window:

1. HBox (Horizontal Box): Arranges its children in a single row.

HBox hbox = new HBox();

2. VBox (Vertical Box): Arranges its children in a single column.

VBox vbox = new VBox();

3. GridPane: Places its children in a grid of rows and columns.

GridPane grid = new GridPane();

4. BorderPane: Divides the scene into five regions: top, bottom, left, right, and center.

BorderPane border = new BorderPane();

5. StackPane: Places its children on top of each other.

StackPane stackPane = new StackPane();


Do It Yourself

1. Design a window with a Label and a Button. Clicking the button should change the label's text.

2. Create a login form using VBox. Add TextField for username and PasswordField for password. Include a
Button for login.

3. Design a layout using HBox where you place three buttons side by side.

4. Create a simple calculator using GridPane. Add buttons for numbers and operations.

5. Use BorderPane to create a dashboard with a navigation bar at the top, content in the center, and a footer at
the bottom.

Quiz

1. Which class in JavaFX is responsible for representing the window?

• A. Stage
• B. Scene
• C. Node
• D. BorderPane

Answer: A. Stage

2. What is the relationship between Scene and Node in JavaFX?

• A. Scene contains Node


• B. Node contains Scene
• C. Both are independent
• D. Scene and Node are interchangeable

Answer: A. Scene contains Node


3. Which layout arranges its children in a single column?

• A. HBox
• B. VBox
• C. GridPane
• D. StackPane
• Answer: B. VBox

4. What method is used to display the primary stage?

• A. show()
• B. launch()
• C. display()
• D. setScene()

Answer: A. show()

5. Which layout is used to organize nodes in rows and columns?

• A. BorderPane
• B. GridPane
• C. VBox
• D. StackPane

Answer: B. GridPane

JavaFX: Displaying Text and Image

Displaying text and images is one of the core functionalities in building JavaFX applications. JavaFX
provides various classes like Label, Text, and ImageView to handle text and images in a user interface
(UI). This material will help engineering students understand how to work with these components to
create visually rich applications.

1. Displaying Text in JavaFX

There are two main ways to display text in JavaFX: using the Label class and the Text class.
1. Label:

• Label is used to display short text or simple information, and it can also hold an image along with text.
• It's often used for UI elements like button labels, headers, etc.

Syntax:

Label label = new Label("Hello, JavaFX!");

2. Text:

• Text is used when you need more control over how the text is displayed, such as setting the font, color, size,
and alignment.

Syntax:

Text text = new Text("This is a Text node");

text.setFont(new Font(20)); // Setting the font size

Example: Displaying Text in JavaFX

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.control.Label;

import javafx.scene.layout.VBox;

import javafx.scene.text.Text;

import javafx.stage.Stage;

public class DisplayTextApp extends Application {

@Override

public void start(Stage primaryStage) {

// Creating a Label

Label label = new Label("Hello, JavaFX!");


// Creating a Text Node

Text text = new Text("This is a more flexible Text element.");

text.setFont(new javafx.scene.text.Font(24));

// Arranging nodes in a vertical box

VBox vbox = new VBox(label, text);

// Creating a scene and adding the layout to it

Scene scene = new Scene(vbox, 300, 200);

primaryStage.setTitle("Displaying Text in JavaFX");

primaryStage.setScene(scene);

primaryStage.show();

public static void main(String[] args) {

launch(args);

Explanation:

• The code demonstrates displaying text using both Label and Text components in a JavaFX application.
• The text is displayed with different formatting, using a VBox layout to arrange them vertically.

2. Displaying Images in JavaFX

To display images in JavaFX, the Image and ImageView classes are used.

1. Image:

• The Image class represents an image that can be loaded from a file, URL, or an input stream.
Syntax:

Image image = new Image("file:src/image.png");

2. ImageView:

• The ImageView class is used to display the image on the screen. It is a Node that can be resized, rotated,
and manipulated in various ways.

Syntax:

ImageView imageView = new ImageView(image);

imageView.setFitHeight(200);

imageView.setFitWidth(200);

Example: Displaying an Image in JavaFX

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.image.Image;

import javafx.scene.image.ImageView;

import javafx.scene.layout.StackPane;

import javafx.stage.Stage;

public class DisplayImageApp extends Application {

@Override

public void start(Stage primaryStage) {

// Loading an image from the local file system

Image image = new Image("file:src/image.png");

// Creating an ImageView to display the image

ImageView imageView = new ImageView(image);


// Resizing the image

imageView.setFitHeight(300);

imageView.setFitWidth(300);

// Creating a layout pane

StackPane root = new StackPane(imageView);

// Creating a scene and adding the layout to it

Scene scene = new Scene(root, 400, 400);

primaryStage.setTitle("Displaying Image in JavaFX");

primaryStage.setScene(scene);

primaryStage.show();

public static void main(String[] args) {

launch(args);

Explanation:

• This code displays an image loaded from a file (src/image.png) using ImageView. The image is resized to
fit the specified dimensions.
Picture of Example Output:

3. Combining Text and Image

JavaFX allows you to display both text and images in the same UI component, like a Label or Button.

Example: Combining Text and Image in a Label

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.control.Label;

import javafx.scene.image.Image;

import javafx.scene.image.ImageView;

import javafx.scene.layout.VBox;

import javafx.stage.Stage;

public class DisplayTextImageApp extends Application {

@Override

public void start(Stage primaryStage) {

// Loading an image

Image image = new Image("file:src/image.png");

ImageView imageView = new ImageView(image);

imageView.setFitHeight(50);

imageView.setFitWidth(50);
// Creating a Label with text and image

Label label = new Label("Image with Text", imageView);

label.setContentDisplay(javafx.scene.control.ContentDisplay.TOP);

// Creating a VBox layout

VBox vbox = new VBox(label);

// Creating a scene and adding the layout to it

Scene scene = new Scene(vbox, 300, 200);

primaryStage.setTitle("Displaying Text and Image");

primaryStage.setScene(scene);

primaryStage.show();

public static void main(String[] args) {

launch(args);

Explanation:

• In this example, both an image and text are displayed inside a Label. The ContentDisplay property controls
the position of the image relative to the text (top, bottom, left, or right).

Do It Yourself

1. Create a JavaFX application that displays a welcome message using a Label and a decorative image below
it.
2. Create a simple image gallery with 3-5 images displayed in an HBox or GridPane.

3. Create a button with both an icon (image) and text. When the button is clicked, display a new image.

4. Create a profile card UI with an image (profile picture) and a name (text) below the image.

5. Create an application where the image can be resized dynamically using sliders to control the width and
height.

Quiz

1. Which class in JavaFX is used to display text with more control over its formatting?

• A. Label
• B. Text
• C. ImageView
• D. Button

Answer: B. Text

2. What method is used to set the image to an ImageView?

• A. setImage()
• B. setGraphic()
• C. setView()
• D. loadImage()

Answer: A. setImage()

3. Which property of a Label allows you to position the image relative to the text?

• A. setImagePosition()
• B. setGraphicPosition()
• C. setContentDisplay()
• D. setLabelPosition()

Answer: C. setContentDisplay()
4. How can you resize an image in JavaFX using ImageView?

• A. setFitHeight() and setFitWidth()


• B. resizeHeight() and resizeWidth()
• C. setHeight() and setWidth()
• D. scaleHeight() and scaleWidth()

Answer: A. setFitHeight() and setFitWidth()

5. Which of the following is a valid constructor for the Image class to load an image from a file?

• A. new Image("src/image.jpg")
• B. new Image("file:src/image.jpg")
• C. new Image("src/image")
• D. new ImageView("file:src/image.jpg")

Answer: B. new Image("file:src/image.jpg")

Event Handling in JavaFX


Event handling is one of the core aspects of JavaFX programming. Events are actions like mouse clicks,
key presses, or any other user interaction. JavaFX provides a robust event-handling mechanism that
allows developers to define responses to such user actions.

1. Overview of Event Handling in JavaFX

JavaFX uses a powerful event-driven programming model. When an event occurs, an object is notified,
and it can respond to the event. There are three main components involved in event handling:

1. Event Source: The object (like a button, text field, etc.) on which the event occurred.
2. Event Object: This encapsulates the details of the event.
3. Event Handler: This handles the event. In JavaFX, it's typically an instance of EventHandler functional
interface.

Common Types of Events:

• Action Events: Triggered by buttons, menu items, etc.


• Mouse Events: Triggered by mouse actions like clicks or movements.
• Key Events: Triggered by keyboard actions.
2. Event Handling Basics

The general process for handling events involves:

• Defining the event source (UI component).


• Attaching an event handler to the event source.
• Defining the logic inside the event handler that is executed when the event occurs.

Syntax for Event Handling:

1. Using setOnAction method: For simple event handling, you can use setOnAction to directly specify what
should happen when an event occurs.

button.setOnAction(new EventHandler<ActionEvent>() {

@Override

public void handle(ActionEvent event) {

// Code to handle event

});

2. Using Lambda Expressions: Lambda expressions simplify event handling by reducing the code required
to attach an event handler.

button.setOnAction(event -> {

// Code to handle the event

});

3. Example: Button Click Event Handling

Code Example: Handling a Button Click

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.control.Button;

import javafx.scene.layout.StackPane;

import javafx.stage.Stage;

public class ButtonClickEventApp extends Application {


@Override

public void start(Stage primaryStage) {

// Creating a Button

Button button = new Button("Click Me");

// Handling Button Click Event using Lambda Expression

button.setOnAction(event -> {

System.out.println("Button was clicked!");

});

// Adding button to layout

StackPane root = new StackPane(button);

// Creating scene and adding layout to it

Scene scene = new Scene(root, 300, 200);

primaryStage.setTitle("Event Handling Example");

primaryStage.setScene(scene);

primaryStage.show();

public static void main(String[] args) {

launch(args);

Explanation:

• This simple application demonstrates event handling by printing a message to the console when the button
is clicked.
• The event handler is attached using a lambda expression.
4. Handling Mouse Events

Mouse events allow you to respond to actions such as mouse clicks, drags, and movements.

Syntax for Handling Mouse Events:

node.setOnMouseClicked(new EventHandler<MouseEvent>() {

@Override

public void handle(MouseEvent event) {

// Code to handle mouse click event

});

Example: Handling Mouse Clicks

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.control.Label;

import javafx.scene.input.MouseEvent;

import javafx.scene.layout.StackPane;

import javafx.stage.Stage;

public class MouseEventApp extends Application {

@Override

public void start(Stage primaryStage) {

// Creating a Label

Label label = new Label("Click me!");

// Handling Mouse Click Event

label.setOnMouseClicked(event -> {

label.setText("Mouse Clicked at X: " + event.getX() + " Y: " + event.getY());


});

// Adding label to layout

StackPane root = new StackPane(label);

// Creating scene and adding layout to it

Scene scene = new Scene(root, 300, 200);

primaryStage.setTitle("Mouse Event Handling");

primaryStage.setScene(scene);

primaryStage.show();

public static void main(String[] args) {

launch(args);

Explanation:

• This code demonstrates handling mouse click events. When the label is clicked, it updates the text to show
the x and y coordinates of the click.

5. Handling Key Events

Key events occur when the user interacts with the keyboard, such as pressing a key, releasing a key, or
typing.

Syntax for Handling Key Events:

node.setOnKeyPressed(new EventHandler<KeyEvent>() {

@Override

public void handle(KeyEvent event) {

// Code to handle key press event

});
Example: Handling Key Presses

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.control.Label;

import javafx.scene.input.KeyEvent;

import javafx.scene.layout.StackPane;

import javafx.stage.Stage;

public class KeyEventApp extends Application {

@Override

public void start(Stage primaryStage) {

// Creating a Label

Label label = new Label("Press a Key");

// Handling Key Press Event

label.setOnKeyPressed(event -> {

label.setText("Key Pressed: " + event.getCode());

});

// Adding label to layout

StackPane root = new StackPane(label);

// Creating scene and adding layout to it

Scene scene = new Scene(root, 300, 200);

// Setting focus to label so it can receive key events

root.setOnMouseClicked(e -> label.requestFocus());

primaryStage.setTitle("Key Event Handling");

primaryStage.setScene(scene);
primaryStage.show();

public static void main(String[] args) {

launch(args);

Explanation:

• The program listens for key press events. When a key is pressed, the label displays the key code.

Do It Yourself

1. Create a JavaFX application that performs basic arithmetic operations (addition, subtraction, multiplication,
and division) using buttons to trigger the calculations.

2. Create an application where a user can draw on the screen by clicking and dragging the mouse.

3. Create a login form with two text fields for username and password. Use button click events to validate the
credentials.

4. Create a small game where an object moves on the screen based on keyboard arrow key inputs.

5. Create a JavaFX app where clicking a button once prints "Clicked!" and double-clicking the button changes
its background color.

Quiz

1. Which of the following is used to handle button click events in JavaFX?

A. setOnKeyPressed()

B. setOnAction()

C. setOnMouseClicked()

D. setOnKeyReleased()

Answer: B. setOnAction()
2. Which interface is commonly used for event handling in JavaFX?

A. EventSource

B. EventObject

C. EventHandler

D. EventStage

Answer: C. EventHandler

3. What is a lambda expression used for in JavaFX?

A. Creating threads

B. Defining anonymous event handlers

C. Handling mouse events only

D. Loading images

Answer: B. Defining anonymous event handlers

4. Which event handler is used to detect mouse clicks?

A. setOnAction()

B. setOnMouseMoved()

C. setOnMouseClicked()

D. setOnMousePressed()

Answer: C. setOnMouseClicked()

5. In which case would you use setOnKeyPressed()?

A. To handle button clicks

B. To handle mouse movement

C. To handle key press events

D. To detect focus changes

Answer: C. To handle key press events


Laying Out Nodes in the Scene Graph (JavaFX)
In JavaFX, all graphical user interface (GUI) elements are represented as nodes in a scene graph. The
scene graph is a hierarchical structure where nodes are arranged in a tree-like manner, forming the
foundation of how elements (UI controls, shapes, text, etc.) are laid out and interact with each other.

1. Understanding the Scene Graph

A scene graph is a data structure that represents a graphical scene. Nodes in this graph can represent
various UI elements, such as controls, layouts, shapes, and other visual elements. The scene graph starts
with a root node, and all other nodes branch out from this root, forming a tree structure.

There are two types of nodes in JavaFX:

1. Leaf Nodes: Represent basic UI components like buttons, labels, text fields, etc.
2. Branch Nodes (Parent Nodes): These nodes group multiple child nodes and are often used to create
layouts. Examples include Pane, HBox, VBox, etc.

2. Types of Layout Panes

JavaFX provides several layout panes that are used to arrange nodes in a scene. Each layout pane
provides a different way of organizing and positioning child nodes.

a) Pane:

A basic layout class that allows child nodes to be positioned freely.

Example:

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.control.Button;

import javafx.scene.layout.Pane;

import javafx.stage.Stage;

public class PaneExample extends Application {

@Override

public void start(Stage primaryStage) {

Pane pane = new Pane();

Button btn = new Button("Click Me");

btn.setLayoutX(100); // Set X position


btn.setLayoutY(50); // Set Y position

pane.getChildren().add(btn);

Scene scene = new Scene(pane, 300, 200);

primaryStage.setTitle("Pane Layout Example");

primaryStage.setScene(scene);

primaryStage.show();

public static void main(String[] args) {

launch(args);

b) HBox:

This layout arranges its child nodes horizontally in a single row.

Example:

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.control.Button;

import javafx.scene.layout.HBox;

import javafx.stage.Stage;

public class HBoxExample extends Application {

@Override

public void start(Stage primaryStage) {

HBox hbox = new HBox(10); // 10px spacing between nodes

Button btn1 = new Button("Button 1");

Button btn2 = new Button("Button 2");


hbox.getChildren().addAll(btn1, btn2);

Scene scene = new Scene(hbox, 300, 200);

primaryStage.setTitle("HBox Layout Example");

primaryStage.setScene(scene);

primaryStage.show();

public static void main(String[] args) {

launch(args);

c) VBox:

This layout arranges its child nodes vertically in a single column.

Example:

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.control.Button;

import javafx.scene.layout.VBox;

import javafx.stage.Stage;

public class VBoxExample extends Application {

@Override

public void start(Stage primaryStage) {

VBox vbox = new VBox(10); // 10px spacing between nodes

Button btn1 = new Button("Button 1");

Button btn2 = new Button("Button 2");

vbox.getChildren().addAll(btn1, btn2);

Scene scene = new Scene(vbox, 300, 200);


primaryStage.setTitle("VBox Layout Example");

primaryStage.setScene(scene);

primaryStage.show();

public static void main(String[] args) {

launch(args);

d) BorderPane:

This layout divides the scene into five regions: top, bottom, left, right, and center.

Example:

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.control.Button;

import javafx.scene.layout.BorderPane;

import javafx.stage.Stage;

public class BorderPaneExample extends Application {

@Override

public void start(Stage primaryStage) {

BorderPane borderPane = new BorderPane();

Button topButton = new Button("Top");

Button bottomButton = new Button("Bottom");

Button leftButton = new Button("Left");

Button rightButton = new Button("Right");

Button centerButton = new Button("Center");


borderPane.setTop(topButton);

borderPane.setBottom(bottomButton);

borderPane.setLeft(leftButton);

borderPane.setRight(rightButton);

borderPane.setCenter(centerButton);

Scene scene = new Scene(borderPane, 300, 200);

primaryStage.setTitle("BorderPane Layout Example");

primaryStage.setScene(scene);

primaryStage.show();

public static void main(String[] args) {

launch(args);

e) GridPane:

This layout allows you to arrange nodes in a grid of rows and columns.

Example:

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.control.Button;

import javafx.scene.layout.GridPane;

import javafx.stage.Stage;

public class GridPaneExample extends Application {

@Override

public void start(Stage primaryStage) {

GridPane gridPane = new GridPane();


Button btn1 = new Button("Button 1");

Button btn2 = new Button("Button 2");

Button btn3 = new Button("Button 3");

gridPane.add(btn1, 0, 0); // Add btn1 at column 0, row 0

gridPane.add(btn2, 1, 0); // Add btn2 at column 1, row 0

gridPane.add(btn3, 0, 1); // Add btn3 at column 0, row 1

Scene scene = new Scene(gridPane, 300, 200);

primaryStage.setTitle("GridPane Layout Example");

primaryStage.setScene(scene);

primaryStage.show();

public static void main(String[] args) {

launch(args);

3. Layout Properties and Alignment

Each layout pane allows you to control how child nodes are arranged through properties like spacing,
alignment, and padding.

• Spacing: Defines the distance between nodes (e.g., VBox and HBox).
• Padding: Defines the space between the content and the edges of the pane.
• Alignment: Determines how nodes are aligned within their pane (e.g., centered, left-aligned, etc.).
Example of Padding and Alignment:

VBox vbox = new VBox(10); // 10px spacing

vbox.setPadding(new Insets(20)); // 20px padding on all sides

vbox.setAlignment(Pos.CENTER); // Center alignment

4. Scene Graph in Action

A Scene in JavaFX can be created by placing a node at the root and then adding child nodes to this root
node, forming a tree-like structure (the scene graph).

Example: Scene Graph with Layout Panes

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.control.Button;

import javafx.scene.layout.HBox;

import javafx.scene.layout.VBox;

import javafx.stage.Stage;

public class SceneGraphExample extends Application {

@Override

public void start(Stage primaryStage) {

Button btn1 = new Button("Button 1");

Button btn2 = new Button("Button 2");

Button btn3 = new Button("Button 3");

HBox hbox = new HBox(10, btn1, btn2); // Add two buttons in an HBox

VBox vbox = new VBox(20, hbox, btn3); // Add the HBox and another button to a VBox

Scene scene = new Scene(vbox, 300, 200);


primaryStage.setTitle("Scene Graph Example");

primaryStage.setScene(scene);

primaryStage.show();

public static void main(String[] args) {

launch(args);

In this example, the layout of nodes in the scene graph is achieved by nesting HBox and VBox layouts.

Do It Yourself

1. Design a form using GridPane layout that collects user details such as name, email, password, and submit it
using a button.

2. Build a calculator interface using GridPane where buttons for numbers and operations (+, -, *, /) are placed
in a grid.

3. Create a JavaFX application using BorderPane where the top, bottom, left, and right regions contain
navigation buttons, and the center displays content.

4. Write a JavaFX app where users can dynamically add buttons to an HBox or VBox by clicking a button.

5. Use GridPane to create a layout for a simple Tic-Tac-Toe game.

Quiz

1. Which of the following is true about VBox?

a) Arranges nodes in a vertical row

b) Arranges nodes in a horizontal row


c) Aligns nodes to the top-left by default

d) Is used for grid-based layouts

Answer: a.Arranges nodes in a vertical row

2. Which layout allows nodes to be arranged freely without any predefined structure?

a) GridPane

b) BorderPane

c) Pane

d) HBox

Answer: c Pane

3. In JavaFX, which class is used to represent the root of a scene graph?

a) Stage

b) Scene

c) Node

d) Parent

Answer: d Parent

4. What is the primary use of BorderPane in JavaFX?

a) To create a grid-like layout

b) To arrange nodes in five distinct regions

c) To freely position nodes anywhere

d) To layout nodes in a vertical column

Answer: b. To arrange nodes in five distinct regions

5. Which of the following methods is used to add padding around nodes in a layout?

a) setPadding()

b) setSpacing()

c) setAlignment()

d) setMargin()
Answer: a.setPadding()

3. Mouse Events in JavaFX

Mouse Events in JavaFX

In JavaFX, mouse events are used to detect and respond to mouse actions such as clicking, pressing,
dragging, or moving the mouse. JavaFX provides a rich API to handle mouse events, allowing
developers to create interactive and user-friendly applications.

The MouseEvent class in JavaFX is used to represent mouse actions, and it provides various methods to
capture information like the mouse's position, button clicks, and whether the mouse is being dragged.

1. Types of Mouse Events

Here are some common types of mouse events in JavaFX:

1. MOUSE_CLICKED: Triggered when the user clicks the mouse button.


2. MOUSE_PRESSED: Triggered when the mouse button is pressed.
3. MOUSE_RELEASED: Triggered when the mouse button is released.
4. MOUSE_MOVED: Triggered when the mouse is moved but not dragged.
5. MOUSE_DRAGGED: Triggered when the mouse is moved while a button is pressed.
6. MOUSE_ENTERED: Triggered when the mouse enters a node (e.g., a button or a pane).
7. MOUSE_EXITED: Triggered when the mouse leaves a node.

2. Handling Mouse Events in JavaFX

To handle mouse events, you need to register an event handler on the node. This is typically done using
the setOnMouseClicked, setOnMousePressed, and similar methods provided by the node class.

3. Example: Handling a Mouse Click Event

Here’s a simple example of handling a mouse click event on a Button:

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.control.Button;

import javafx.scene.input.MouseEvent;

import javafx.scene.layout.StackPane;

import javafx.stage.Stage;
public class MouseEventExample extends Application {

@Override

public void start(Stage primaryStage) {

Button btn = new Button("Click Me");

// Registering a mouse click event

btn.setOnMouseClicked((MouseEvent event) -> {

System.out.println("Button clicked at position: " + event.getScreenX() + ", " +


event.getScreenY());

});

StackPane root = new StackPane();

root.getChildren().add(btn);

Scene scene = new Scene(root, 300, 250);

primaryStage.setTitle("Mouse Event Example");

primaryStage.setScene(scene);

primaryStage.show();

public static void main(String[] args) {

launch(args);

In this example, when the button is clicked, the program prints the coordinates of the click to the
console.

4. Example: Mouse Drag and Movement

Mouse dragging is another commonly used feature, where actions are performed when the user holds the
mouse button and moves the mouse.

Example: Dragging a Circle


import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.input.MouseEvent;

import javafx.scene.paint.Color;

import javafx.scene.shape.Circle;

import javafx.scene.layout.Pane;

import javafx.stage.Stage;

public class MouseDragExample extends Application {

@Override

public void start(Stage primaryStage) {

Pane pane = new Pane();

Circle circle = new Circle(50, 50, 30);

circle.setFill(Color.BLUE);

// Registering mouse dragged event

circle.setOnMouseDragged((MouseEvent event) -> {

circle.setCenterX(event.getX());

circle.setCenterY(event.getY());

});

pane.getChildren().add(circle);

Scene scene = new Scene(pane, 400, 300);

primaryStage.setTitle("Mouse Drag Example");

primaryStage.setScene(scene);

primaryStage.show();
}

public static void main(String[] args) {

launch(args);

This program allows you to click and drag the circle across the window. The circle’s center moves with
the mouse's movement while the button is pressed.

5. Mouse Event Properties

The MouseEvent class provides several methods to retrieve information about the mouse event:

• getX() and getY(): These methods return the mouse’s x and y coordinates relative to the node.
• getSceneX() and getSceneY(): These methods return the mouse’s coordinates relative to the scene.
• getScreenX() and getScreenY(): These methods return the mouse’s coordinates relative to the screen.
• isPrimaryButtonDown(): This method checks if the primary (usually left) mouse button is pressed.
• isSecondaryButtonDown(): This method checks if the secondary (usually right) mouse button is pressed.

6. Mouse Event Example with Multiple Event Types

In some cases, you might want to handle multiple types of mouse events for a node, such as
MOUSE_ENTERED and MOUSE_EXITED.

import javafx.application.Application;

import javafx.scene.Scene;

import javafx.scene.control.Label;

import javafx.scene.layout.StackPane;

import javafx.stage.Stage;

public class MouseMultipleEventsExample extends Application {

@Override

public void start(Stage primaryStage) {

Label label = new Label("Hover over me!");

// Mouse entered event

label.setOnMouseEntered(event -> {
label.setText("Mouse Entered");

});

// Mouse exited event

label.setOnMouseExited(event -> {

label.setText("Hover over me!");

});

StackPane root = new StackPane();

root.getChildren().add(label);

Scene scene = new Scene(root, 300, 200);

primaryStage.setTitle("Multiple Mouse Events Example");

primaryStage.setScene(scene);

primaryStage.show();

public static void main(String[] args) {

launch(args);

In this example, when the mouse enters the label, the text changes to “Mouse Entered,” and when the
mouse leaves, it reverts to “Hover over me!”

Do It Yourself

1. Create a JavaFX application where clicking on different regions of the window changes the background
color of a Pane or Rectangle.
2. Build an application where users can drag multiple shapes (e.g., circles, squares) across the window.

3. Create an application that continuously tracks and displays the current mouse coordinates within a Pane.

4. Build an application where right-clicking an image zooms in, and left-clicking zooms out.

Quiz

1. Which method is used to get the X-coordinate of the mouse relative to the node?

a) getScreenX()

b) getX()

c) getSceneX()

d) getLocalX()

Answer: b. getX()

2. What event is triggered when the user moves the mouse with the button pressed?

a) MOUSE_DRAGGED

b) MOUSE_CLICKED

c) MOUSE_MOVED

d) MOUSE_PRESSED

Answer: a. MOUSE_DRAGGED

3. Which method checks if the primary mouse button is pressed?

a) isPrimaryButtonPressed()

b) isPrimaryButtonDown()

c) isButtonDown()

d) isButtonPressed()

Answer: b. isPrimaryButtonDown()
4. What is the purpose of the setOnMouseDragged() method?

a) To handle mouse clicks

b) To track mouse movement

c) To detect mouse release

d) To handle mouse drags

Answer: d To handle mouse drags

5. Which mouse event is typically used to detect a hover action over a node?

a) MOUSE_CLICKED

b) MOUSE_ENTERED

c) MOUSE_RELEASED

d) MOUSE_DRAGGED

Answer: b,MOUSE_ENTERED

References

Creating mouse events in JavaFX - Creating MouseEvents for JavaFX

Java GUI Mouse event demo - JavaFX GUI - Handling Mouse Event Demos

You might also like