Multi Threading
Multi Threading
synchronized (lockObject) {
// Critical section code
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
buffer.produce(i);
// Simulate varying production times
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
buffer.consume();
// Simulate varying consumption times
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class ProducerConsumerExample {
public static void main(String[] args) {
Buffer buffer = new Buffer(5);
Thread producerThread = new Thread(new Producer(buffer));
Thread consumerThread = new Thread(new Consumer(buffer));
producerThread.start();
consumerThread.start();
}
}
Deadlock:
Occurs when threads are waiting for each other to release resources, forming
a circular dependency.
All involved threads are blocked and unable to proceed.
In our producer-consumer example, we avoid deadlock by using a single lock
(the intrinsic lock of the Buffer object) and carefully managing when threads
wait and notify.
Livelock:
Occurs when threads are actively running but unable to make progress.
Unlike deadlock, threads are not blocked, but they're stuck in a loop of
responses to each other.
In a producer-consumer scenario, a livelock could occur if the producer and
consumer continuously yield to each other without actually producing or
consuming.