0% found this document useful (0 votes)
2 views

Java programming notes

The document provides an overview of threads and multithreading in Java, explaining key concepts such as thread creation, synchronization, and the thread lifecycle. It details the benefits of multithreading, including improved responsiveness and resource utilization, and outlines methods for creating threads via the Thread class and Runnable interface. Additionally, it discusses thread synchronization to prevent race conditions and the importance of managing thread states for efficient concurrent execution.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF or read online on Scribd
0% found this document useful (0 votes)
2 views

Java programming notes

The document provides an overview of threads and multithreading in Java, explaining key concepts such as thread creation, synchronization, and the thread lifecycle. It details the benefits of multithreading, including improved responsiveness and resource utilization, and outlines methods for creating threads via the Thread class and Runnable interface. Additionally, it discusses thread synchronization to prevent race conditions and the importance of managing thread states for efficient concurrent execution.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF or read online on Scribd
You are on page 1/ 31
« Threads and Multithreading concepts Threads and multithreading form the backbone of concurrent programming in Java, allowing your applications to perform multiple tasks seemingly simultaneously. What is a Thread? - Lightweight Process: A thread is like a mini-process within a process, representing a single sequence of execution. - Sharing Resources: Threads within the same process share the same memory space and resources, enabling efficient communication and data exchange. - Independent Execution: Each thread runs independently, with its own execution path and stack Multithreading: - Concurrent Execution: Multithreading allows multiple threads to execute concurrently within a single process. While it may appear as if tasks are happening simultaneously, the threads are actually taking turns utilizing the CPU. - Multiprocessing and multithreading, both are used to achieve multitasking. But we use multithreading than multiprocessing because threads share a common memory area. They don't allocate separate memory area so saves memory, and context-switching between the threads takes less time than process - Benefits of Multithreading: - Responsiveness: Keeps the application responsive even when performing time- consuming tasks. ~ Resource Utilization: Efficiently utilizes CPU resources by switching between threads when one is waiting for I/O or other operations. - Performance: Improves application performance, especially on multi-core processors. - Independent: It doesn't block the user because threads are independent and you can perform multiple operations at same time -Exception Handling: Threads are independent so it doesn't affect other threads if exception occur in a single thread Creating Threads in Jaya: There are two primary ways to create threads in Java: 1. Extending the Thread Class: ~ Define a class that extends the “Thread” class. - Override the *run()’ method with the code you want the thread to execute. = Create an instance of your class and call the *start()" method to initiate the thread, 2. Implementing the Runnable Interface: - Define a class that implements the ‘Runnable’ interface. - Implement the ‘run()’ method with the desired thread code. - Create an instance of your class and pass it to a “Thread’ object's constructor, - Start the thread using the “start()’ method on the “Thread” object. Thread Synchronization and Communication: - Race Conditions: Concurrent access to shared resources can lead to unpredictable results and errors. - Synchronization Mechanisms: Java provides mechanisms like synchronized methods, synchronized blocks, and locks to ensure that only one thread can access a shared resource at atime, preventing race conditions. = Inter-thread Communication: Mechanisms like wait(), notify(), and notifyAll() enable threads to communicate and coordinate their activities. Thread Pool - Managing Threads: Creating and destroying threads repeatedly can be inefficient. - Thread Pool: A pool of pre-created threads ready to execute tasks. - Benefits: Improves performance and resource utilization by reusing threads and avoiding the overhead of thread creation, + Thread Life Cycle (Thread States) A thread in Java goes through various stages during its lifetime, from creation to termination. Understanding this lifecycle is crucial for effectively managing and working with threads in your applications. According to sun, there is only 4 states in thread life cycle in java new, runnable, non- runnable and terminated. There is no running state. But for better understanding the threads, we are explaining it in the 5 states start() sleepdone, 1/0 complete,lockavailable, resume , notify Runnable Non-Runnable ae” sleep, blockon /O, wait forlock, suspend, wait ‘The Life Cycle Stages: 1. New: - The thread is created using either the “Thread’ class constructor or by implementing the *Runnable* interface and passing it to a ‘Thread’ object. At this stage, the thread is not yet alive and hasn't started execution, 2. Runnable: - The thread enters the runnable state when the “start()° method is invoked on the “Thread” object. - It's now eligible to be picked by the JVM for execution. However, it may not necessarily be running immediately, as the JVM schedules threads based on priority and other factors. 3. Running: - The thread is ai ly executing its code within the “run()’ method. - It continues to run until one of the following occurs: ) The ‘run()’ method completes its execution naturally. b) An exception is thrown within the "run() method, causing the thread to terminate abruptly. ©) The thread is interrupted by another thread. Blocked/Waiting: ~A thread enters the blocked or waiting state when it's temporarily inactive, waiting for a specific event or resource. - This can occur due to various reasons, such as: a) Waiting for /O operations to complete b) Acquiring a lock on a synchronized resource that is currently held by another thread. ©) Calling methods like “sleep)’ or ‘wait()’ which explicitly put the thread in a waiting state. 5. Timed Waiting: - Similar to the blocked/waiting state, but with a specified time limit. - The thread waits for a certain amount of time or until a specific event occurs, - Examples include using methods like ‘sleep(millis)’ or ‘wait(millis)’ 6. Terminated: - The thread reaches the terminated state when its "run()’ method completes execution or it's terminated due to an exception or interruption, - Once terminated, a thread cannot be restarted, Key Points: ~ A thread can transition between these states’ multiple times during its lifetime. - The JVM manages the scheduling and execution of threads, and the exact timing of state transitions can be unpredictable. - Understanding the lifecycle helps identify potential issues like deadlocks or starvation where threads are perpetually blocked or waiting for resources. - Using appropriate synchronization and thread management techniques is crucial for ensuring smooth and efficient concurrent execution. Thread Sleep In Java, the ‘Thread.sleep()’ method allows you to pause the execution of the current thread for a specified amount of time. This can be useful for various purposes, such as: = Introducing delays: You might need to wait for a certain event or resource to become available before proceeding. - Simulating real-world timing: In simulations or games, you can use sleep to control the pace of actions or events. - Rate limiting: Sleep can be used to control the frequency of operations, preventing overload or excessive resource usage. How to Use ‘Thread.sleep(” try { Thread sleep(milliseconds); // Pause for the specified time in milliseconds } catch (InterruptedException e) { 1/ Handle the exception if the sleep is interrupted Arguments: * Milliseconds: The amount of time to sleep, specified in milliseconds. Important Points: - Checked Exception: ‘Thread.sleep()’ throws an ‘InterruptedException’ if the sleeping thread is interrupted before the specified time has elapsed. You must handle this exception using a try-catch block. - Thread State: While sleeping, the thread is in a "blocked" state and does not consume CPU resources. - Precision: The actual sleep duration might not be exactly the same as the specified milliseconds due to factors like system scheduling. Alternatives to “Thread sleep() -TimeUnit’ class: Provides methods for converting time units and sleeping with more readable code: TimeUnit. SECONDS sleep(5); // Sleep for 5 seconds * Object.wait()’ and ‘Object notify()'/ Object. notify AII(": Used for thread synchronization and communication, where one thread waits for a specific condition to be met before continuing. Example: class A extends Thread { public void run() { for(int i=1si<-Ssit+) { System.out.printin(" try { Thread.sleep(1000); / Sleep for 1 second } catch (InterruptedException e) { e.printStackTrace(); Hy class B extends Thread { public void run() { for(int i Siit+) { System.out.printin("hello"); mt public class ThreadDemo4 { public static void main(String [] args) { Aobjl = new AQ; B obj2 —new BO; obj start(); obj2.start(); wh Output: hi hello hello hello hello hello hi hi hi hi ¢ Thread Creation: Runnable Interface and Thread Class There are two primary ways to create threads in Java: 1. Extending the Thread Class: - Define a class that extends the ‘Thread’ class. - Override the “run()’ method with the code you want the thread to execute. ~ Create an instance of your class and call the “start()’ method to initiate the thread. - Multiple Inheritance is not supported by Java. So, extending a thread is not a good practice to follow. 2. Implementing the Runnable Interface: - Define a class that implements the ‘Runnable’ interface. - Implement the ‘run()’ method with the desired thread code. - Create an instance of your class and pass it to a “Thread” object's constructor. - Start the thread using the ‘start()’ method on the “Thread’ object. - Thread is a class that implements Runnable and Runnable contains a method known as the run() method. - Instead of extending a thread, we can also implement it through an interface called Runnable. eg, class A implements Runnable {public void run() { statements; } } - In the Runnable method, the start() method is not present so we cannot use it by implementing Runnable simply. - Thread has multiple constructors and one of the constructors takes a runnable object - We cannot create an object of a thread by using a class name. = Objects for a thread will be created by using a Runnable keyword. So, we create a reference of an interface and an object of a class e.g., Runnable obj = new AQ); = We have to pass a reference to an object in the thread class. After creating a reference of the Runnable class, we can use the start() method with the thread. - The runnable interface does not have thread methods, in that ease, we need to create a separate thread object to use features. - We can also instantiate a runnable interface by using an anonymous class ~ Runnable is a functional interface so we also use lambda expression with it. ‘Thread class: Thread elass provide constructors and methods to create and perform operations on a thread. Thread elass extends Object class and implements Runnable interface. Commonly used Constructors of Thread class: - Thread() - Thread(String name) - Thread(Runnable r) - Thread(Runnable r,String name) Commonly used methods of Thread cla: 1. public void run() is used to perform aetion for a thread. 2. public void start(): starts the execution of the thread. JVM calls the run() method on the thread. 3. public void sleep(long milliseconds): Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds. 4, public void join(): waits for a thread to die. 5. public void join(long milliseconds): waits for a thread to die for the specified milliseconds. 6. publi int getPriority(): returns the priority of the thread. 7. public int setPriority(int priority): changes the priority of the thread. 8. public String getName(): returns the name of the thread. 9. public void setName (String name): changes the name of the thread. 10. public Thread current Thread(): retums the reference of currently executing thread, 11. public int getld(): returns the id of the thread. 12. public Thread. State getState(): returns the state of the thread 13. public boolean isAlive(): tests if the thread is alive. 14. public void yield(): causes the currently executing thread object to temporarily pause and allow other threads to execute. 15. public void suspend(): is used to suspend the thread(depricated). 16, public void resume(): is used to resume the suspended thread(depricated). 17. public void stop(): is used to stop the thread(depricated). 18. public boolean isDaemon(): tests if the thread is a daemon thread. 19. public void setDaemon(boolean b): marks the thread as daemon or user thread. 20. public void interrupt(): interrupts the thread. 21. public boolean isInterrupted(): tests if the thread has been interrupted. 22. publie static boolean interrupted(): tests if the current thread has been interrupted. # Daemon thread in Java is a service provider thread that provides services to the user thread. Its life depend on the merey of user threads i.e. when all the user threads dies, JVM terminates this thread automatically. There are many java dacmon threads running automatically e.g. gc, finalizer ete. Runnable interface: The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread. Runnable interface have only one method named run(). 1. public void run(): is used to perform action for a thread. Starting a thread: start() method of Thread class is used to start a newly created thread, It performs following tasks: - Anew thread starts(with new callstack), - The thread moves from New state to the Runnable state. - When the thread gets a chance to execute, its target run() method will run. Java Thread Example by extending Thread class class Multi extends Thread { public void run(){ System.out printin( "thread is running..."); } public static void main(String args{]){ Multi t=new Multi(); tl start(); H Output: thread is running. Java Thread Example by implementing Runnable interface class Multi3 implements Runnable { public void runQ){ System.out printin("thread is running...” } public static void main(String args[]){ Multi3 mi-new Multi3(); Thread t1 new Thread(m!); t1.start(); By Output: thread is running... «© Thread Pri ity Each thread has a priority. Priorities are represented by a number between | and 10. In most cases, thread schedular schedules the threads according to their priority (known as pre- emptive scheduling). But it is not guaranteed because it depends on JVM specification that which scheduling it chooses 3 constants defined in Thread class: 1. public static int MIN_PRIORITY 2. public static int NORM_PRIORITY 3. public static int MAX_PRIORITY Default priority of a thread is $ (NORM_PRIORITY). The value of MIN_PRIORITY is 1 and the value of MAX_PRIORITY is 10. Example of priority of a Thread: class TestMultiPriority! extends Thread { public void run(){ System out printin("running thread name is:"*+Thread.currentThread().getName()); ‘System.out.println( "running thread priority is"+Thread.currentThread().getPriority()); } public static void main(String args{]) { TestMultiPriority! ml=new TestMultiPriority1(); ‘TestMultiPriority! m2=new TestMultiPriority1(); m1 setPriority(Thread. MIN_PRIORITY); m2.setPriority(Thread MAX_PRIORITY); ml start(); m2.start(); i Output: running thread name is:Thread-0 0 running thread priority i running thread name is:Thread-1 running thread priority is:1 « Thread Synchronization When we start two or more threads within a program, there may be a situation when multiple threads try to access the same resource and finally, they ean produce unforeseen result due to concurrency issues. For example, if multiple threads try to write within a same file, then they may corrupt the data because one of the threads can override data or while one thread is, opening the same file at the same time another thread might be closing the same file. So, there is a need to synchronize the action of multiple threads and make sure that only one thread can access the resource at a given point in time. This is implemented using a concept called monitors. Each object in Java is associated with a monitor, which a thread can lock or unlock. Only one thread at a time may hold a lock on a monitor. Monitor in Java Concurrency is a synchronization mechanism that provides the fundamental requirements of multithreading namely mutual exclusion between various threads and cooperation among threads working at common tasks. Monitors basically ‘monitor’ the access control of shared resources and objects among threads. Using this construct only one thread at a time gets access control over the critical section at the resource while other threads are blocked and made to wait until certain conditions. In Java, monitors are implemented using synchronized keyword (synchronized blocks, synchronized methods or classes). Java programming language provides a very handy way of creating threads and synchronizing their task by using synchronized blocks. You keep shared resources within this, block. Following is the general form of the synchronized statement ~ synchronized (objectidentifier) { 1/ Access shared variables and other shared resources Here, the objectidentifier is a reference to an object whose lock associates with the monitor that the synchronized statement represents. If you declare any method as synchronized, it is known as synchronized method. Synchronized method is used to lock an object for any shared resource. When a thread invokes a synchronized method, it automatically acquires the lock for that object and releases it when the thread completes its task. Example class Counter { private int count = 0; public void increment() { synchronized(this) { count++5 System.out printin("“Incremented count to: " + count); ay class SyneBlockExample { public static void main(String[] args) { Counter counter = new Counter(); // Creating multiple threads to increment the count Thread thread = new Thread(() > { for (int i=0;1< 5; 544) { counter.increment(); HDs Thread thread? = new Thread(() > { for (inti=0;1 { for (int i=0;1< 5; i++) { counter.increment(); Ds Thread thread: ew Thread(() -> { for (int i= 0; 1<5;i+*) { counter.inerement(); HDs 1/ Start the threads thread 1 start(); thread2.start(); 1/ Wait for threads to finish yt thread! join; thread2 join); } catch (InterruptedException e) { e.printStackTrace(); aH Output - Incremented count to: 1 Incremented count to: 2 Incremented count to: 3 Incremented count to: 4 Incremented count to: 5 Incremented count to: 6 7 Incremented count to: Incremented count to: 8 Incremented count to: 9 Incremented count to: 10 Explanation: 1. ‘Counter’ Class: ~ Contains a ‘count’ variable to keep track of the shared data. - Defines a method “increment()° that increments the “count” variable. ~ Key Feature: The ‘inerement()’ method is declared as “synchronized”. This means that only one thread can execute this method at a time. 2. *SynchronizationMethodExample’ Class: ~ Creates a ‘Counter’ object. ~ Creates two threads ("thread1* and “thread2°) that both call the “increment()’ method of the ‘Counter’ object. ~ Starts the threads. ~ Waits for the threads to finish using * The output of this program will show the ‘count’ being incremented to 1, 2,3, ... 10. The exact order of the increments might vary depending on thread scheduling, but the final value will always be 10, demonstrating that the synchronization prevents data corruption. How it Works: - The ‘synchronized’ keyword applied to the “increment()" method acts as a lock. - When one thread enters the ‘increment()’ method, it acquires the lock, preventing other threads from entering the method until the first thread finishes. - This ensures that the “count” variable is modified atomically and consistently, avoiding race conditions. Key Points: - Atomic Operations: The ‘increment()” method becomes a single, indivisible operation due to the synchronization. - Thread Safety: The ‘synchronized’ method effectively makes the ‘Counter’ class thread safe, allowing multiple threads to access the shared data without issues. - Lock Contention: If many threads try to execute the synchronized method concurrently, there might be some performance overhead as threads wait for their turn to acquire the lock. Why is Thread Synchronization Necessary? Imagine you have a shared resource, like a bank account. Multiple threads (representing customers) might try to access and modify it concurrently. Without synchronization, things can go wrong: * Race Conditions: Threads might interleave their operations in ways that lead to unexpected results. For example, two threads trying to withdraw money might both see the same balance, resulting in an overdraft. * Data Corruption: Data can become inconsistent if multiple threads modify it without proper coordination. Imagine two threads incrementing a counter; the final value might be incorrect. Key Synchronization Mechanisms in Java Java offers several ways to achieve thread synchronization: 1. “synchronized” Keyword: Synchronized Blocks: You can surround the critical section (code that modifies shared resources) with a ‘synchronized’ block. This ensures only one thread can execute the code within the block at a time. public class Counter { private int count = 0; public synchronized void increment() { count++; hb Synchronized Methods: The entire method is synchronized, making it atomic. public class Counter { private int count = 0; public synchronized int incrementAndGet() { count++; return count; My 2. ‘ReentrantLock’ - More Control: Provides more flexibility than ‘synchronized’ blocks. You can acquire and release the lock explicitly. ~ Reentrancy: A thread can acquire the same lock multiple times (useful for recursive methods). import java.util concurrent.locks ReentrantLock; public class Counter { private int count = 0; private ReentrantLock lock = new ReentrantLock(); public void increment() { lock.lock(); try {count } finally { lock.unlock(); uy 3. ‘volatile’ Keyword: - Visibility: Ensures that changes to a variable are visible to all threads. - Not Synchronization: Doesn't provide mutual exclusion. public class SharedData { volatile boolean flag = false; i Example: Shared Counter public class Counter { private int count ~ 0; private ReentrantLock lock = new ReentrantLock(); public void increment() { lock-lock(); // Acquire lock uy t count++ } finally { lock.unlock(); // Release lock public int getCount() { return count; iM How Thread Synchronization Works - Locks: Synchronization mechanisms typically rely on underlying locks. When a thread acquires a lock, it prevents other threads from accessing the protected resource. - Wait/Notify: Synchronization can also involve threads waiting for certain conditions to be met (using ‘wait()") and being notified when they are (using “notify()’ or ‘notifyAlI(). Key Concepts - Critical Section: The code that needs protection from concurrent access. - Mutual Exclusion: Only one thread can execute the critical section at a time. - Atomic Operations: Operations that appear in multiple steps. sible to other threads, even if they involve - Deadlock: When two or more threads are blocked indefinitely, each waiting for the other to release a resource. - Liveness: Ensuring that your program doesn't become unresponsive due to synehronization issues + Deadlocks A deadlock happens when two or more threads are blocked indefinitely, each waiting for the other to release a resouree it needs. - Thread A holds resource X and wants to acquire resource Y. - Thread B holds resource Y and wants to acquire resource X. Both threads are stuck, unable to proceed, and the program becomes unresponsive. “synchronized” keyword is used to make the class or method thread-safe which means only one thread can have the lock of the synchronized method and use it, other threads have to wait till the lock releases and anyone of them acquire that lock. Itis important to use if our program is running in a multi-threaded environment where two or more threads execute simultaneously. But sometimes it also causes a problem which is called Deadlock. Below is a simple example of the Deadlock condition. 2 —@ 2 wee (I) cscs - Mutual Exclusion: Only one thread can use a resource at a time (ike a lock). Causes of Deadlock - Hold and Wait: A thread holds a resource while waiting for another. - No Preemption: A thread cannot forcibly take a resource from another. - Circular Wait: A cycle where thread A waits for B, B waits for C, and C waits for A. Avoid Dead Lock condition We can avoid dead lock condition by knowing its possibilities. It’s a very complex process and not easy to catch. But still if we try, we can avoid this. There are some methods by which wwe can avoid this condition. We can’t completely remove its possibility but we can reduce Avoid Nested Locks: This is the main reason for dead lock. Dead Lock mainly happens when we give locks to multiple threads. Avoid giving lock to multiple threads if we already have given to one, Avoid Unnecessary Locks: We should have lock only those members which are required. Having lock on unnecessarily can lead to dead lock. Using thread join: Dead lock condition appears when one thread is waiting other to finish. If this condition occurs we can use Thread,join with maximum time you think the execution will take. File Handling using Jav: Stream A series of data is referred to as a stream. In Java, Stream is classified into two types, ie., Byte Stream and Character Stream. Input stream Classes Byte Stream Output stream Classes SS) Reader Classes Character Stream . Writer Classes TS) Brief classification of I/O streams Byte Stream Byte Stream is mainly involved with byte data. A file handling process with a byte strean process in which an input is provided and executed with the byte data. Character Stream Character Stream is mainly involved with character data. A file handling process with a character stream is a process in which an input is provided and executed with the character data Java File Class Methods 1 canRead() Boolean | The eanRead() method is used to check whether ‘we can read the data of the file or not. 2. createNewFile() Boolean The createNewFile() method is used to create a new empty file. 3 canWrite() Boolean | The eanWrite() method is used to check whether ‘we can write the data into the file or not. 4, exists() Boolean The exists() method is used to check whether the specified file is present or not. 5 delete() Boolean The delete() method is used to delete a file. 6. getName() String The getName) method is used to find the file name. 7. getAbsolutePath() String The getAbsolutePath() method is used to get the absolute pathname of the file. 8. Iength() Long The length() method is used to get the size of the file in bytes. 9. list) String[] | The list() method is used to get an array of the files available in the directory. 10. mkdir) Boolean The mkdir() method is used for creating a new directory. File Operations We can perform the following operation on a file: -Create a File -Get File Information -Write to a File -Read from a File -Delete a File File Operations in Java Lia Mi Maar Get File Write toa Information File Read From a Delete a File File Create a File Create a File Create a File operation is performed to create a new file. We use the createNewFile() method of file. The ereateNewFile() method returns true when it successfully creates @ new file and returns false when the file already exists. Let's take an example of creating a file to understand how we can use the createNewFile() method to perform this operation. CreateFile java // Importing File class import java.io File; Importing the TOException class for handling errors import java.io.IOException; class CreateFile { public static void main(String args[]) { try { (/ Creating an object of a file File £0 = new File("D:FileOperationExample txt") if (10.createNewFile()) { System.out printhn("File " + f0.getName() +" is created successfully."); } else { System.out printIn( "File is already exist in the directory."); } } catch (IOException exception) { System .out.printin(""An unexpected error is occurred.’ exception printStackTrace(); uh Explanation: In the above code, we import the File and IOException class for performing file operation and handling errors, respectively. We create the £0 object of the File class and specify the location of the directory where we want to create a file. In the try block, we call the ereateNewFile() method through the f0 object to create a new file in the specified location If the method returns false, it will jump to the else section. If there is any error, it gets handled in the catch block Get File Information The operation is performed to get the file information. We use several methods to get the information about the file like name, absolute path, is readable, is writable and length. FileInfo.java // Import the File class import java.io.File; class FileInfo { public static void main(String[] args) { // Creating file object File £0 = new File("D:FileOperationExample.txt"); if (exists) { // Getting file name System.out printin("The name of the file is: " + f0.getName()); / Getting path of the file System.out printIn(""The absolute path of the file is: " + f0.getAbsolutePath()); 1/ Checking whether the file is writable or not System out printin( "Is file writeable?: " + f0.canWrite()); 1/ Checking whether the file is readable or not System.out printin("Is file readable " + f0.canRead()); / Getting the length of the file in bytes System.out printin(""The size of the file in bytes is: " + f0.length); } else { System.out printIn("The file does not exist."); uw Description: In the above code, we import the java.io.File package and create a class FileInfo. In the main method, we create an object of the text file which we have created in our previous example. We check the existence of the file using a conditional statement, and if itis present, we get the following information about that file: We get the name of the file using the getName() We get the absolute path of the file using the getAbsolutePath() method of the file. We check whether we can write data into a file or not using the canWrite() We check whether we can read the data of the file or not using the canRead() We get the length of the file by using the length() If the file doesn't exist, we show a custom message. Write to a File The next operation which we can perform on a file is "writing into a file". In order to write data into a file, we will use the FileWriter class and its write() method together. We need to close the stream using the close() method to retrieve the allocated resources. WriteToFi java / Importing the FileWriter class import java.io FileWriter; // Importing the IOException class for handling errors import java.io. IOException; class WriteToFile { public static void main(String[] args) { try { FileWriter fivrite = new FileWriter("D:FileOperationExample.txt"); // writing the content into the FileOperationExample.txt file fwrite.write("A named location used to store related information is referred to as a File.); 1/ Closing the stream fwrite.close(); System.out printIn("Content is successfully wrote to the file."); } catch (IOException e) { System.out printIn("Unexpected error occurred"); ce printStackTrace(); Ww Explanatic In the above code, we import the java.io.FileWriter and java.io. IOException classes. We create a class WriteToFile, and in its main method, we use the try-catch block. In the try section, we create an instance of the FileWriter class, ie., fwrite. We call the write method of the FileWriter class and pass the content to that function which we want to write, After that, we call the close() method of the FileWriter class to close the file stream. After writing the content and closing the stream, we print a custom message Ifwe get any error in the try section, it jumps to the catch block. In the catch block, we handle the IOException and print a custom message. Read from a File The next operation which we can perform on a file is "read from a file". In order to write data into a file, we will use the Scanner class. Here, we need to close the stream using the close() method. We will create an instance of the Scanner class and use the hasNextLine() method nextLine() method to get data from the file. ReadFromFile.java 1 Importing the File class import java.io File; Importing FileNotFoundException class for handling errors import java.io.FileNotFoundException; 1 Importing the Scanner class for reading text files import java.util. Scanner; class ReadFromFile { public static void main(String[] args) { try { / Create f1 object of the file to read data File fl = new File("D:FileOperationExample.txt"); Scanner dataReader = new Scanner( 1); while (dataReader hasNextLine()) { String fileData = dataReader.nextLine(); System.out.printIn(fileData); i dataReader.close(); } catch (FileNotFoundException exception) { ‘System.out.printIn("Unexcpected error occurred!"); exception printStackTrace(); wy Explanation: We import the "java.util Scannner”,"java.io.File” and "java.io. OException” classes. We create a class ReadFromFile, and in its main method, we use the try-eatch block. In the try section, ‘we create an instance of both the Scanner and the File classes. We pass the File class object to the Scanner class object and then iterate the scanner class object using the "While" loop and print each line of the file. We also need to close the scanner class object, so we use the close() function. If we get any error in the try section, it jumps to the catch block. In the catch block, we handle the IOException and print a custom message. Delete a File The next operation which we can perform on a file is "deleting a file". In order to delete a file, we will use the delete method of the file. We don't need to close the stream using the elose() method because for deleting a file, we neither use the FileWriter class nor the Scanner class. DeleteFile,java / Importing the File class import java.io File; class DeleteFile { public static void main(String] args) { File £0 = new File("D:FileOperationExample.txt"); if (f0.delete()) { ‘System.out printin({0.getName()+" file is deleted successfull } else { System. out printIn("Unexpected error found in deletion of the file."); 3} Explanation: In the above code, we import the File class and create a class DeleteFile. In the main() method of the class, we create f0 object of the file which we want to delete. In the if statement, we call the delete() method of the file using the 10 object. If the delete() method returns true, we print the success custom message. Otherwise, it jumps to the else section where we print the unsuccessful custom message. All the above-mentioned operations are used to read, write, delete, and create file programmatically. © Write a program in java to copy content of a file into another file using file handling import java.io.BufferedReader; import java.io BufferedWriter; import java.io FileReader; import java.io.FileWriter; import java.io. IOException; public class FileCopier { public static void main(String[] args) { String sourceFile = "source.txt"; // Name of the source file String destinationFile = "destination.txt"; // Name of the destination file try (BufferedReader reader ~ new BufferedReader(new FileReader(sourceFile)); Buffered Writer writer = new Buffered Writer(new FileWriter(destinationFile))) { String line; while ((line = reader.readLine()) != null) { writer.write(line); writernewLine(); // Add a new line to the destination file i System.out printin("File copied successfull } catch (IOException e) { System.errprintin("An error occurred: " + e.getMessage()); wa Explanation: 1. Import Necessary Classes: ‘BufferedReader’: Reads data from a file line by line. “Buffered Writer’: Writes data to a file line by line. “FileReader’: Opens a file for reading. “FileWriter’: Opens a file for writing. ‘IOException’: Handles exceptions related to input/output operations. 2. Define File Paths: ~ ‘soureeFile’: The name of the file you want to copy (replace "source.txt" with your actual file name). ~ ‘destinationFile’: The name of the file where you want to copy the content (replace "destination.txt" with your desired file name). 3. Try-with-Resources Block: = The “try’ block ensures that the resources (“BufferedReader’ and “BufferedWriter’) are automatically closed after they are used, preventing resource leaks. - ‘BufferedReader reader’: Creates a ‘BufferedReader’ to read from the source file. - ‘BufferedWriter writer’: Creates a ‘BufferedWriter’ to write to the destination file. 4, Read and Write Lines: ~ String line;*: Declares a variable ‘line* to store each line read from the source file. ~ ‘while (line = reader.readLine()) != null)": Reads lines from the source file until the end of the file is reached (‘null’) = ‘writer.write(line);": Writes the read line to the destination file. ~ ‘writernewLine();": Adds @ newline character to the destination file to maintain proper formatting. 5. Error Handling: - The ‘catch’ block catches any IOException’ that might occur during the file operations. How to Run: 1. Create Source File: Create a file named "source.txt" in the same directory as your Java file and add some text to it. 2. Compile the Program: Compile the Java file using ‘javae FileCopierjava’. 3. Run the Program: Run the program using ‘java FileCopier’ 4. Check Destination File: After execution, a new file named "destination.txt" will be created in the same directory, containing the copied content. © Write a program in java to create two threads, one thread will print odd numbers and second thread will print even numbers between 1 to 20 numbers. public class OddEvenThreads { public static void main(String[] args) { 1/ Create two threads ‘Thread oddThread ew Thread(new OdePrinter()); Thread evenThread = new Thread(new EvenPrinter()); 1/ Start the threads oddThread.start(); evenThread.start(); uy Thread to print odd numbers class OddPrinter implements Runnable { @Overtide public void run() { for (int i= 1; i<=20;i+=2) { System.out printin("Odd: " + i); try { Thread.sleep(100); // Pause for 100 milliseconds } catch (InterruptedException e) { System.errprintIn("Thread interrupted: " + e.getMessage()); ih 1 Thread to print even numbers class EvenPrinter implements Runnable { @Override public void run() { for (int i= 2; i<=20;1+=2) { System. out printIn("Even: try { Thread.sleep(100); // Pause for 100 milliseconds } catch (InterruptedException e) { System.errprintIn("Thread interrupted: Way + egetMessage()); Explanation: 1. ‘OddEvenThreads’ Class: - This class contains the ‘main’ method where the program execution starts. = Itereates two ‘Thread’ objects, ‘oddThread’ and ‘evenThread’, and assigns them instances of ‘OddPrinter’ and "EvenPrinter’ respectively, which implement the ‘Runnable’ interface. 2. ‘OddPrinter’ and ‘EvenPrinter® Classes: - Both classes implement the “Runnable” interface, which means they can be executed as threads. ~‘run()’ Method: - The *run()" method is the entry point for each thread. ~ ‘OdePrinter’ iterates from 1 to 20 in increments of 2, printing each odd number. - “BvenPrinter’ iterates from 2 to 20 in increments of 2, printing each even number. - ‘Thread.sleep(100)": This introduces a small delay to allow the threads to interleave their output, making it easier to see the alternating pattern. 3, ‘main’ Method: ~ It starts both threads using ‘oddThread.start()’ and ‘evenThread.start(). This causes the “run()’ methods of the ‘OddPrinter’ and “EvenPrinter’ classes to be executed concurrently. How it Works: - When you run this program, the ‘OddPrinter’ and “EvenPrinter’ threads will start running independently. - The threads will altemate printing odd and even numbers to the console. = The ‘Thread. sleep()’ call ensures that each thread pauses for a brief moment before printing the next number, giving the other thread a chance to execute

You might also like