Exercise-7
A)
class GoodMorningRunnable implements Runnable {
public void run() {
while (true) {
System.out.println("Good Morning");
try {
Thread.sleep(1000); // Sleep for 1 second
} catch (InterruptedException e) {
e.printStackTrace();
class HelloRunnable implements Runnable {
public void run() {
while (true) {
System.out.println("Hello");
try {
Thread.sleep(2000); // Sleep for 2 seconds
} catch (InterruptedException e) {
e.printStackTrace();
class WelcomeRunnable implements Runnable {
public void run() {
while (true) {
System.out.println("Welcome");
try {
Thread.sleep(3000); // Sleep for 3 seconds
} catch (InterruptedException e) {
e.printStackTrace();
public class RunnableExample {
public static void main(String[] args) {
Thread thread1 = new Thread(new GoodMorningRunnable());
Thread thread2 = new Thread(new HelloRunnable());
Thread thread3 = new Thread(new WelcomeRunnable());
thread1.start();
thread2.start();
thread3.start();
OUTPUT:
Hello From Thread-1
Good Morning FromThread-0
Welcome From Thread-2
Good Morning FromThread-0
Hello From Thread-1
Good Morning FromThread-0
Welcome From Thread-2
Good Morning FromThread-0
Hello From Thread-1
Good Morning FromThread-0
Good Morning FromThread-0
Welcome From Thread-2
B)
class TaskThread extends Thread {
public void run() {
try {
System.out.println("TaskThread is starting...");
Thread.sleep(3000); // Simulating a task that takes 3 seconds
System.out.println("TaskThread has completed.");
} catch (InterruptedException e) {
System.out.println("TaskThread was interrupted.");
}
public class ThreadAliveJoinExample {
public static void main(String[] args) {
TaskThread taskThread = new TaskThread();
// Start the thread
taskThread.start();
// Check if the thread is alive before join
System.out.println("Is TaskThread alive? " + taskThread.isAlive());
try {
// Wait for the taskThread to finish
taskThread.join();
} catch (InterruptedException e) {
System.out.println("Main thread was interrupted while waiting.");
// Check if the thread is alive after join
System.out.println("Is TaskThread alive after join? " + taskThread.isAlive());
// Main thread continues after taskThread has completed
System.out.println("Main thread is continuing after TaskThread has completed.");
OUTPUT:
TaskThread is starting...
Is TaskThread alive? true
TaskThread has completed.
Is TaskThread alive after join? false
Main thread is continuing after TaskThread has completed.
C)
class DaemonThread extends Thread {
public void run() {
while (true) {
try {
System.out.println("Daemon thread is running...");
Thread.sleep(1000); // Sleep for 1 second
} catch (InterruptedException e) {
System.out.println("Daemon thread was interrupted.");
public class DaemonThreadExample {
public static void main(String[] args) {
// Create a daemon thread
DaemonThread daemonThread = new DaemonThread();
daemonThread.setDaemon(true); // Set the thread as a daemon
daemonThread.start(); // Start the daemon thread
// Main thread performs its task
for (int i = 0; i < 5; i++) {
System.out.println("Main thread is running... " + (i + 1));
try {
Thread.sleep(2000); // Sleep for 2 seconds
} catch (InterruptedException e) {
System.out.println("Main thread was interrupted.");
System.out.println("Main thread is ending. Daemon thread will also stop.");
OUTPUT:
Daemon thread is running...
Main thread is running... 1
Daemon thread is running...
Main thread is running... 2
Daemon thread is running...
Daemon thread is running...
Main thread is running... 3
Daemon thread is running...
Daemon thread is running...
Main thread is running... 4
Daemon thread is running...
Daemon thread is running...
Main thread is running... 5
Daemon thread is running...
Daemon thread is running...
Main thread is ending. Daemon thread will also stop.
D)
import java.util.LinkedList;
import java.util.Queue;
class SharedBuffer {
private final Queue<Integer> queue = new LinkedList<>();
private final int capacity;
public SharedBuffer(int capacity) {
this.capacity = capacity;
public synchronized void produce(int value) throws InterruptedException {
while (queue.size() == capacity) {
wait(); // Wait until there is space in the buffer
queue.add(value);
System.out.println("Produced: " + value);
notifyAll(); // Notify consumers that an item is available
public synchronized int consume() throws InterruptedException {
while (queue.isEmpty()) {
wait(); // Wait until there is an item to consume
int value = queue.poll();
System.out.println("Consumed: " + value);
notifyAll(); // Notify producers that there is space in the buffer
return value;
}
class Producer implements Runnable {
private final SharedBuffer buffer;
public Producer(SharedBuffer buffer) {
this.buffer = buffer;
public void run() {
for (int i = 0; i < 10; i++) {
try {
buffer.produce(i);
Thread.sleep(100); // Simulate time taken to produce
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
class Consumer implements Runnable {
private final SharedBuffer buffer;
public Consumer(SharedBuffer buffer) {
this.buffer = buffer;
public void run() {
for (int i = 0; i < 10; i++) {
try {
buffer.consume();
Thread.sleep(150); // Simulate time taken to consume
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
public class ProducerConsumerExample {
public static void main(String[] args) {
SharedBuffer buffer = new SharedBuffer(5); // Buffer capacity of 5
Thread producerThread = new Thread(new Producer(buffer));
Thread consumerThread = new Thread(new Consumer(buffer));
producerThread.start();
consumerThread.start();
try {
producerThread.join();
consumerThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("Production and consumption completed.");
}
OUTPUT:
Produced: 0
Consumed: 0
Produced: 1
Consumed: 1
Produced: 2
Produced: 3
Consumed: 2
Produced: 4
Consumed: 3
Consumed: 4
Production and consumption completed.