I am working on a IRC bot that has the command !Scouter and it will generate a random number.... I already have that done, what I wanted to make was a cool down system to keep from people spamming it over and over again.
here is my code.
public class Twitchbot extends PircBot {
Random dice = new Random();
int number;
for(int counter=1; counter<=1;counter++) {
number = 1+dice.nextInt(9001);
System.out.println(number + " ");
}
public Twitchbot() {
this.setName("Blah");
}
public void onMessage(String channel, String sender, String login, String hostname, String message) {
if (message.equalsIgnoreCase("!Scouter")) {
sendMessage(channel,": The time is now " + sender + number);
for(int counter=1; counter<=1;counter++) {
number = 1+dice.nextInt(9001);
System.out.println(number + " ");
try {
Thread.sleep(5000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
}
}
I tried using this code for a cool down
try {
Thread.sleep(5000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
but all it did is do the code after 5 seconds of sleeping. I don't want the command !Scouter to register during that cool down. is there a better way of doing it?
You could save the current system-time on a successfull call using:
lastCall = System.currentTimeMillis();
and before, you check
if(System.currentTimeMillis() - lastCall >= DELAY)
where DELAY is a time in milliseconds (1 second equals 1000 milliseconds).
if that statement is true, set lastCall to the current time:
lastCall = System.currentTimeMillis();
and call the normal code.
It would look something like this:
long lastCall = 0L; //Initializing
public void onMessage(String channel, String sender,
String login, String hostname, String message) {
if (message.equalsIgnoreCase("!Scouter")) {
if(System.currentTimeMillis() - lastCall >= 5000)
{
lastCall = System.currentTimeMillis(); // Set lastCall again
sendMessage(channel,": The time is now " + sender + number);
for(int counter=1; counter<=1;counter++) {
number = 1+dice.nextInt(9001);
System.out.println(number + " ");
}
}
}
}
The problem is that onMessage is called asynchronously, so you cannot prevent it from being called with a sleep.
The easiest workaround is to store the current time as an instance variable, and return immediately in onMessage if the difference between the stored time and the current time is less than 5 seconds.
I don't fully understand the functionality of your system, but I see that your system gets stuck everytime it enters on Sleep.
If you want to get rid of this behavior, a good approach would be to use a Thread as an anonymous class call, and do the things in background.
I would do it like this:
if (message.equalsIgnoreCase("!Scouter")) {
sendMessage(channel,": The time is now " + sender + number);
new Thread() {
#Override
public void run() {
for(int counter=1; counter<=1;counter++) {
number = 1+dice.nextInt(9001);
System.out.println(number + " ");
try {
sleep(5000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
}.run();
}
Hope it helps.
Related
I'm a beginner in java, and I just started using threads yesterday. I'm having a problem accessing variables in a thread, which I want to display.
Long story short, I made a (shitty) clock loop, that runs when the program starts. After certain actions, I have a method that checks the time, but I don't know how to access the variables in the thread to make this possible.
This is my main method:
public static void main(String[] args) {
Thread timeRunning = new Thread(new Clock());
Clock clock = new Clock();
Commands command = new Commands();
timeRunning.start();
command.whatsTheTime();
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
command.whatsTheTime();
This is my clock loop:
public class Clock implements Runnable{
public void run(){
//Time
int seconds = 0;
int minutes = 0;
int hours = 0;
//"Clock" loop
while(hours < 24) {
while (minutes < 59) {
while (seconds < 59) {
seconds++;
try {
Thread.sleep(30);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
if(seconds == 59) {
minutes++;
seconds = 0;
}
if(minutes == 59) {
hours++;
minutes = 0;
}
}
}
}
}
This is the "whatsTheTime()" method:
public void whatsTheTime() {
System.out.println("The time is: " + clock.hours + ":" + clock.minutes + ":" + clock.seconds);
}
But it doesn't work. What I want to know is, how can I access the seconds, minutes and hours from the run() in the Clock class.
I'm sorry if this is a very basic question, but I don't know how to access it. I tried googling the solution, but can't seem to find it. I might be seraching for the wrong thing, but as I said, I'm only a few months into java, so searching for the solution is one of the things I need to get better at aswell.
In the problem I am trying to solve, each thread has to read the whole file, (maybe each thread will deliver its content to another task or any other purpose). After reading it, the thread should sleep a bit then try to read the file again, and only a given number(n) of threads should read the file. My attempt to solve this dealing with controling the amount of threads working is in the code below :
import java.util.*;
class Reader implements Runnable{
Thread t;
Controler c;
public Reader(Controler c){
t = new Thread(this);
this.c = c;
t.start();
}
public void run(){
Random ran = new Random();
int napTime;
while(true){
try{
w.intentarLeerArchivo(t);
//Specification says that each reader
//should wait a bit before trying to
//read the file again
napTime = ran.nextInt(1000);
t.sleep(napTime);
}catch(InterruptedException e){
System.out.println("InterruptedException");
}
}
}
}
class Controler{
Random ran;
LinkedList <Reader> readers;
int n;
int count;
public Controler(int n){
readers = new LinkedList <Reader>();
this.n = n;
count = 0;
ran = new Random();
}
public synchronized void getPermission(){
try{
while(count >= n){
wait();
}
notify();
}catch(InterruptedException e){
System.out.println("InterruptedException");
}
}
public synchronized void increaseCount(){
count++;
}
public synchronized void decreaseCount(){
count--;
System.out.println("There are " + count + " threads reading");
}
public void intentarLeerArchivo(Thread t){
int readTime = 1000;
try{
getPermission();
System.out.println("Thread " + t.getId() +" empezó a leer");
increaseCount();
t.sleep(readTime);
System.out.println("Thread " + t.getId() +" is reading");
System.out.println("Thread " + t.getId() + " finished reading");
decreaseCount();
} catch(InterruptedException e){
System.out.println("InterruptedException");
}
}
}
class Initializer{
int numReaders;
int maxReaders;
public Initializer(int numReaders, int maxReaders){
this.numReaders = numReaders;
this.maxReaders = maxReaders;
}
public void init(){
Controler c = new Controler(maxReaders);
for(int i = 0; i < numReaders; i++){
new Reader(c);
}
}
}
public class FileShare{
public static void main(String [] args){
Initializer c = new Initializer(100, 50);
c.init();
}
}
There are a few lines I wrote in order to debug. They print the state of each thread and the number of threads that are reading whenever one of them ends reading. But when I run the program, it turns out that suddenly there are more Threads reading the file than the ones there were supposed to be doing so. I guess it has something to do with my synchronization manipulation. What am I doing wrong?
When a thread is in the
while(...){wait()}
section of your implementation, it wait until someone notify it to go on. Right now, when you finish waiting, you notify right away.
Think about it, if once I get in I notify someone to come, he will not wait until I'm done before coming in. You want to use notify when you leave the file.
So I have been trying to sort this out for a couple of hours now and I'm sure its something really simple or just a simple mistake i am missing but i have a three class program, control, account and MyThreads.
Im trying to have multipule threads(cards) modify the single account, i'm trying to use a monitor so only one thread can make changes at a time, this is not what i have archived I have somehow just allowed the one thread to access the account class and no others, they seem to just disappear, i assume they are just all on wait but refuse to wake up... any help before i implode?
account code:
class account{
private static int value = 0;
private static int cards = 0;
private static int count = 0;
private static int lock = 0;
public void setValue(int temp){
value = temp;
}
public int getValue(){
// while(lock == 1){
// try{
// wait();
// }catch (InterruptedException e){
// }
// }
return value;
}
synchronized public void withdraw(int temp, String tempID){
while(lock == 1){
try{
wait();
}catch (InterruptedException e){}
}
lock=1;
value= value - temp;
count++;
System.out.println(count + "(" + tempID +")"+" "+temp+" - "+value);
lock = 0;
this.notifyAll();
}
synchronized public void deposit(int temp, String tempID){
while(lock == 1){
try{
wait();
}catch (InterruptedException e){}
}
lock=1;
value= value + temp;
count++;
System.out.println(count + "(" + tempID +")"+" - "+temp+" "+value);
lock = 0;
this.notifyAll();
}
public void setCards(int temp){
cards = temp;
}
public int getCards(){
return cards;
}
public int getCount(){
return count;
}
}
control code:
class control{
public static void main(String [] args){
account acc = new account();
acc.setValue(1000);
acc.setCards(5);
// if(args.length > 0){
// try{
// int tempCards = Integer.parseInt(args[0]);
//
// }catch (NumberFormatException e) {
// System.err.println("Number of Cards : " + args[0] + " must be an integer.");
// System.exit(1);
// }
// try{
// int tempVal = 0;
// tempVal = Integer.parseInt(args[1]);
// acc.setValue(tempVal);
// }catch (NumberFormatException e) {
// System.err.println("Account Value : " + args[1] + " must be an integer.");
// System.exit(1);
// }
// }else{
// System.err.println("No values found, please start program with the number of Cards and Bank Account Value, both in integer format");
// System.exit(1);
// }
System.out.println("Transaction Withdrawal Deposit Balance");
System.out.println(" " + acc.getValue());
for(int i=0; i<=((acc.getCards())-1); i++){
new MyThreads(Integer.toString(i+1));
}
}
}
MyThreads code:
class MyThreads implements Runnable{
private String ID;
private Thread t;
account acc = new account();
MyThreads(String tempID){
ID = tempID;
t = new Thread(this, ID);
t.start();
}
public void run(){
try{
for (int i = 0; i < 20; i++){
if(Math.random()>0.5){
int tempW = 0;
tempW = ((int)(Math.random()*100));
acc.withdraw(tempW, this.ID);
//System.out.println(acc.getCount() + "(" + this.ID +")"+" "+tempW+" -"+acc.getValue());
}else{
int tempD = 0;
tempD = ((int)(Math.random()*100));
acc.deposit(tempD, this.ID);
//System.out.println(acc.getCount() + "(" + this.ID +")"+" "+" - "+tempD+" "+acc.getValue());
}
t.sleep(500);
}
} catch (InterruptedException e) {
System.out.println("Thread " + ID + " interrupted.");
}
System.out.println("Thread " + ID + " exiting.");
}
}
I know its a mess, forgive me im lazy.
Have a look at the definition of a Monitor in Java. In your code, you use the keyword synchronized for two methods, which are the same as:
public void XX(){
lock.lock(); // lock is a private variable
try {
// code here
} finally {
lock.unlock();
}
}
In short, It is a shorthand for explicit locking and will prevent multiple threads to access the methods concurrently.
So, just remove the lock part (i.e. the while(lock==1) block) inside your synchronized methods and it will work. Also, if in other codes you need a real lock, use the Lock class, not an integer.
For more information, there are a lot of good introduction to multithreading on the web, for example this one.
Your question, and thus answer, is a wonderful mixture of static synchronized and wait-notify that's neve being called. Why use static? sounds like a magic word? skip static and make life easier.
Also note that a wait-notify is related to a specific object; if wait-notify are related to different objects they will not communicate. Have a single object that they all synchronize around.
I am currently making a hypothetical producer consumer problem using java. The object is to have an operating system which is 1000 bytes, but only 500 bytes available to use for threads as 500 bytes have already been consumed by drivers and other operations. The threads are as follows:
A thread to start a BubbleWitch2 session of 10 seconds, which requires 100 bytes of RAM per
second
A thread to start a Spotify stream of 20 seconds, which requires 250 bytes of RAM per second
You should also take into account the fact that the operating system is simultaneously supporting system
activity and managing the processor, memory and disk space of the device on which it is installed.
Therefore, additionally create:
System and management threads, which, together, require 50 bytes of RAM per second, and
execute for a random length of time, once invoked.
A thread to install a new security update of 2 KB, which will be stored to disk, and requires 150
bytes of RAM per second while installing. Assume sufficient disk capacity in the system to support
this thread.
The operating system has only capacity for 200 bytes per second, therefore a larger thread such as spotify will experience delays or be forced to wait. I have used code which as far as I can tell, implements this. I am also required to generate exit times which I have done with timestamps and to calculate average waiting times for threads.
I have included code in my solution for the average waiting times with system.out.print but no matter what I do, it is not actually outputting the times at all-as if they did not exist.
I am also not sure if the buffer size limitations are working as it is a matter of milliseconds-is there any way to tell if this is working from the code below?
My main method.
public class ProducerConsumerTest {
public static void main(String[] args) throws InterruptedException {
Buffer c = new Buffer();
BubbleWitch2 p1 = new BubbleWitch2(c,1);
Processor c1 = new Processor(c, 1);
Spotify p2 = new Spotify(c, 2);
SystemManagement p3 = new SystemManagement(c, 3);
SecurityUpdate p4 = new SecurityUpdate(c, 4, p1, p2, p3);
p1.setName("BubbleWitch2 ");
p2.setName("Spotify ");
p3.setName("System Management ");
p4.setName("Security Update ");
p1.setPriority(10);
p2.setPriority(10);
p3.setPriority(10);
p4.setPriority(5);
c1.start();
p1.start();
p2.start();
p3.start();
p4.start();
p2.join();
p3.join();
p4.join();
System.exit(0);
}
}
My buffer class
import java.text.DateFormat;
import java.text.SimpleDateFormat;
/**
* Created by Rory on 10/08/2014.
*/
class Buffer {
private int contents, count = 0, process = 0;
private boolean available = false;
private long start, end, wait, request= 0;
private DateFormat time = new SimpleDateFormat("mm:ss:SSS");
public synchronized int get() {
while (process <= 500) {
try {
wait();
} catch (InterruptedException e) {
}
}
process -= 200;
System.out.println("CPU After Process " + process);
notifyAll();
return contents;
}
public synchronized void put(int value) {
while (process >= 1000) {
start = System.currentTimeMillis();
try {
wait();
} catch (InterruptedException e) {
}
end = System.currentTimeMillis();
wait = end - start;
count++;
request += wait;
System.out.println("Application Request Wait Time: " + time.format(wait));
process += value;
contents = value;
notifyAll();
}
}
}
My security update class
import java.lang.*;
import java.lang.System;
/**
* Created by Rory on 11/08/2014.
*/
class SecurityUpdate extends Thread {
private Buffer buffer;
private int number;
private int bytes = 150;
private int process = 0;
public SecurityUpdate(Buffer c, int number, BubbleWitch2 bubbleWitch2, Spotify spotify, SystemManagement systemManagement) throws InterruptedException {
buffer = c;
this.number = number;
bubbleWitch2.join();
spotify.join();
systemManagement.join();
}
public void run() {
for (int i = 0; i < 15; i++) {
buffer.put(i);
System.out.println(getName() + this.number
+ " put: " + i);
try {
sleep(1500);
} catch (InterruptedException e) {
}
}
System.out.println("-----------------------------");
System.out.println("Security Update has finished executing.");
System.out.println("------------------------------");
}
}
My processor class
class Processor extends Thread {
private Buffer processor;
private int number;
public Processor(Buffer c, int number) {
processor = c;
this.number = number;
}
public void run() {
int value = 0;
for (int i = 0; i < 60; i++) {
value = processor.get();
System.out.println("Processor #"
+ this.number
+ " got: " + value);
}
}
}
My bubblewitch class
import java.lang.*;
import java.lang.System;
import java.sql.Timestamp;
/**
* Created by Rory on 10/08/2014.
*/
class BubbleWitch2 extends Thread {
private Buffer buffer;
private int number;
private int bytes = 100;
private int duration;
public BubbleWitch2(Buffer c, int pduration) {
buffer = c;
duration = pduration;
}
long startTime = System.currentTimeMillis();
public void run() {
for (int i = 0; i < 10; i++) {
buffer.put(bytes);
System.out.println(getName() + this.number
+ " put: " + i);
try {
sleep(1000);
} catch (InterruptedException e) {
}
}
long endTime = System.currentTimeMillis();
long timeTaken = endTime - startTime;
java.util.Date date = new java.util.Date();
System.out.println("-----------------------------");
System.out.println("BubbleWitch2 has finished executing.");
System.out.println("Time taken to execute was " +timeTaken+ " milliseconds");
System.out.println("Time Bubblewitch2 thread exited Processor was " + new Timestamp(date.getTime()));
System.out.println("-----------------------------");
}
}
My system management
class SystemManagement extends Thread {
private Buffer buffer;
private int number, min = 1, max = 15;
private int loopCount = (int) (Math.random() * (max - min));
private int bytes = 50;
private int process = 0;
public SystemManagement(Buffer c, int number) {
buffer = c;
this.number = number;
}
public void run() {
for (int i = 0; i < loopCount; i++) {
buffer.put(50);
System.out.println(getName() + this.number
+ " put: " + i);
try {
sleep(1000);
} catch (InterruptedException e) {
}
}
System.out.println("-----------------------------");
System.out.println("System Management has finished executing.");
System.out.println("-----------------------------");
}
}
My spotify class
import java.sql.Timestamp;
/**
* Created by Rory on 11/08/2014.
*/
class Spotify extends Thread {
private Buffer buffer;
private int number;
private int bytes = 250;
public Spotify(Buffer c, int number) {
buffer = c;
this.number = number;
}
long startTime = System.currentTimeMillis();
public void run() {
for (int i = 0; i < 20; i++) {
buffer.put(bytes);
System.out.println(getName() + this.number
+ " put: " + i);
try {
sleep(1000);
} catch (InterruptedException e) {
}
}
long endTime = System.currentTimeMillis();
long timeTaken = endTime - startTime;
java.util.Date date = new java.util.Date();
System.out.println(new Timestamp(date.getTime()));
System.out.println("-----------------------------");
System.out.println("Spotify has finished executing.");
System.out.println("Time taken to execute was " + timeTaken + " milliseconds");
System.out.println("Time that Spotify thread exited Processor was " + date);
System.out.println("-----------------------------");
}
}
I may need to add timestamps to one or two classes yet but does anyone have any idea how to get my average times to actually print out? Or what is preventing it and if the buffer limitation is effectively being shown here(given that we are talking about milliseconds?)
Thanks.
The reason why sys out's are not printing is because of the below condition in your buffer class:-
public synchronized void put(int value) {
while (process >= 1000) {
.....
notifyAll();
}
}
this condition never gets satisified as the process never is greater than 1000
This is the reason why your Processor thread also gets stuck because when it calls get() it finds that the process is less than 500 and hence it indefinitely waits when it reaches the wait() line of code.
Rectifying the process condition appropriately in your put should let your missing sys out get printed
public synchronized void put(int value) {
if(process <= 500) {
process+=value;
} else {
//while (process >= 1000) {
start = System.currentTimeMillis();
try {
wait();
} catch (InterruptedException e) {
}
end = System.currentTimeMillis();
wait = end - start;
count++;
request += wait;
System.out.println("Application Request Wait Time: " + time.format(wait));
process += value;
contents = value;
//}
}
notifyAll();
}
If you want securityupdate thread to always run at the last then the correct way of using join within that thread is as below:-
class SecurityUpdate extends Thread {
private Buffer buffer;
private int number;
private int bytes = 150;
private int process = 0;
private BubbleWitch2 bubbleWitch2;
private Spotify spotify;
private SystemManagement systemManagement;
public SecurityUpdate(Buffer c, int number, BubbleWitch2 bubbleWitch2, Spotify spotify, SystemManagement systemManagement) throws InterruptedException {
buffer = c;
this.number = number;
this.bubbleWitch2 = bubbleWitch2;
this.spotify = spotify;
this.systemManagement = systemManagement;
}
public void run() {
try {
bubbleWitch2.join();
spotify.join();
systemManagement.join();
} catch (InterruptedException e) {
}
System.out.println("Finally starting the security update");
for (int i = 0; i < 15; i++) {
buffer.put(bytes); // Paul check if it should be i or bytes
System.out.println(getName() + this.number
+ " put: " + i);
try {
sleep(1500); // Paul why is this made to sleep 1500 seconds?
} catch (InterruptedException e) {
}
}
System.out.println("-----------------------------");
System.out.println("Security Update has finished executing.");
System.out.println("------------------------------");
}
}
Though the below is well known topic I want Your ideas please.
I had written a small program as below: All the producers are queued up and also the consumers. I couldn't understand why it is so. What are the scenarios where it can block completely.
Let us consider Producers/consumers are waiting for lock on array and what making consumers /producers to exit out the synchronized block. I mean it has to move atleast slowly but deadlock must not happen. I believe.
Here I have 2 questions:
1. What are the scenarios that deadlock is happening.
2. How to understand what is happening under the hood. I mean how to debug.
public class ProducerConsumer implements Runnable {
boolean producer = false;
private volatile int i = 0;
int[] array = new int[10];
public static String getThreadName() {
return Thread.currentThread().getName();
}
public void producer() {
try {
synchronized (array) {
while (i > 9) {
System.out.println("Producer of " + getThreadName()
+ " is waiting i " + i);
array.wait();
System.out.println("Producer of " + getThreadName()
+ " came out of sleep i " + i);
}
System.out.println("Producer of " + getThreadName()
+ " in synchronized block i" + i);
array[i] = generateRandom();
System.out.println("Producer of " + getThreadName()
+ " inserted in array " + array[i] + " index " + i);
i++;
array.notifyAll();
}
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("Producer of " + getThreadName()
+ " interrupted " + e);
}
}
public void consumer() {
try {
synchronized (array) {
while (i < 0) {
System.out.println("Consumer of " + getThreadName()
+ " is waiting i " + i);
array.wait();
System.out.println("Consumer of " + getThreadName()
+ " came out of sleep i " + i);
}
System.out.println("Consumer of " + getThreadName()
+ " in synchronized block extracted value " + array[i]
+ " of index " + i);
i--;
array.notifyAll();
}
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("Consumer of " + getThreadName()
+ " interrupted " + e);
}
}
public static int generateRandom() {
Random random = new Random();
return random.nextInt(10);
}
public static void main(String[] args) {
ProducerConsumer pc = new ProducerConsumer();
for (int i = 0; i < 4; i++) {
if (i % 2 == 0)
new Thread(pc, "producer thread").start();
else {
new Thread(pc, "consumer thread").start();
}
}
}
public void run() {
while (true) {
if (getThreadName().equalsIgnoreCase("producer thread")) {
producer();
} else {
consumer();
}
}
}
}
It struck as below output:
Consumer of consumer thread in synchronized block extracted value 0 of index 0
Producer of producer thread in synchronized block i-1
Producer of producer thread in synchronized block i-1
Consumer of consumer thread is waiting i -1
Consumer of consumer thread is waiting i -1
Your code is incorrect in many places.
I expect that all threads just finish with exceptions, either because of
IllegalMonitorException (calling notify() on ProducerConsumer object
but there is no synchronized block on this ProducerConsumer object)
ArrayIndexOfBoundsException (i can become 10 in produce() method)
Have you checked error output?
Java provides a neat implementation of concurrent programs via its java.util.concurrent package. So rather than trying to reinvent the wheel, and getting it all wrong, you should use the Concurrent API to handle locking in a safer way. Here's a simulation of a Producer-Consumer:
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* We want a Producer thread to create random values, and the Consumer thread to
* consume it. One caveat is that if the Producer has already created a random
* value, which the Consumer thread hasn't consumed yet, the Producer thread
* blocks or waits. On the flip side, the Consumer thread waits for the Producer
* thread to produce some value if the Producer thread hasn't already.
* <p/>
* Write a Program to simulate such a situation.
*/
public class ProducerConsumerCommunication
{
private volatile boolean running = true;
private ArrayBlockingQueue<Integer> buffer = new ArrayBlockingQueue<>(1);
private Random random = new Random(System.currentTimeMillis());
public ProducerConsumerCommunication()
{
ExecutorService service = Executors.newCachedThreadPool();
service.execute(new ProducerTask());
service.execute(new ConsumerTask());
service.shutdown();
}
public static void main(String[] args)
{
new ProducerConsumerCommunication();
}
private class ProducerTask implements Runnable
{
public void run()
{
while (running)
{
try
{
Thread.sleep(random.nextInt(2000));
Integer value = random.nextInt();
buffer.put(value); // Blocks if buffer is full.
System.out.println("Value Put: " + value);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
private class ConsumerTask implements Runnable
{
public void run()
{
while (running)
{
try
{
Thread.sleep(random.nextInt(2000));
Integer value = buffer.take(); // Blocks if buffer is empty.
System.out.println("Value Taken: " + value);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}
Try running it and see for yourself as to how easy and intuitive it is to implement such scenarios using the Concurrent API. It also keeps your code clean and lets you focus on the problem at hand.
Reasons for deadlock in Producer Consumer problem aren't that many. If one thread has lock on an object A and is waiting for lock on object B to be released, while if other thread has lock on object B at the same time and is waiting for lock on object A to be released, deadlock situation arises.