Thread problem :(
Hi Everyone,
I'am currently working on this question:
Write a producer-consumer problem that uses threads and shares a common buffer. However do not use semaphores or any other synchronization primitives to guard the shared data structures. Just let each thread access them when it wants to. Use sleep and wakeup to handle the full and empty conditions. See how long it takes for a fatal race condition to occur. For example you might have the producer print a number once in a while. Do not print that number every minute because the I/O could affect the race conditions.
This is what I managed to do:
import java.lang.*;
import java.nio.*;
publicclass Producerextends Thread{
private Buffer sharedBuf;// the buffer is the buffer class above
// constructor should accept (Buffer), and set it to the sharedBuf ...
public Producer (Buffer sharedBuf){
this.sharedBuf=sharedBuf;
}
publicvoid threadRun()throws InterruptedException
{
for (int i=1; i<=4; i++)
{
sleep(1);//sleep for a random time, between 0-3 seconds for example;
sharedBuf.set(i);
}
System.out.println("Producer finished, exiting...");
}
}
publicclass Buffer{
privateint buffer = -1;
publicvoid set(int val)
{
System.out.println("Writing" + val);
buffer = val;
}
publicint get()
{
System.out.println("Reading" + buffer);
return buffer;
}
}
publicclass Consumerextends Thread{
private Buffer sharedBuf;// the buffer is the same buffer used by the producer
int sum = 0;// total stuff read from the buffer
//..constructor should accept(Buffer), and set it to the sharedBuf ...
public Consumer (Buffer sharedBuf){
this.sharedBuf=sharedBuf;
}
publicvoid threadRun()throws InterruptedException{
// read the buffer four times, and keep the total
for (int i=1; i<=4; i++)
{
sleep(1);
sum = sum + sharedBuf.get();
}
System.out.println("Consumer finished, ate " + sum +"exiting...");
}
}
publicclass test{
publicstaticvoid main(String args[]){
Buffer shared =new Buffer();
Producer prod =new Producer( shared );
Consumer cons =new Consumer( shared );
prod.start();
cons.start();
}
}
I did this much, but im not getting any output !!?!!?........the other thing is that I dont know where I should put my wakeup statements.
Hope you can help me out,
thanks in advance
Do implement runnable.. it good.do start it like thisThread a=new Thread( new producer());a.start();
thanks for your help G_Abubakr !!
I did what you told me and I also did some minor modifactions, but im still not geeting the output. This is the first program that i do using threads, thats why im having problems.
this is the code i fixed:
import java.lang.*;
import java.nio.*;
public class Producer extends Thread implements Runnable{
private Buffer sharedBuf; // the buffer is the buffer class above
// constructor should accept (Buffer), and set it to the sharedBuf ...
public Producer (Buffer sharedBuf){
this.sharedBuf=sharedBuf;
}
public void threadRun()throws InterruptedException
{
try{
for (int i=1; i<=4; i++)
{
//sleep for a random time, between 0-3 seconds for xample;
sleep(1);
sharedBuf.set(i);
}
}
catch (InterruptedException exception) {
exception.printStackTrace();
}
System.out.println("Producer finished, exiting...");
}
}
import java.nio.*;
public class Buffer {
private int buffer = -1;
public void set(int val)
{
System.out.println("Writing" + val);
buffer = val;
}
public int get()
{
System.out.println("Reading" + buffer);
return buffer;
}
}
import java.lang.*;
import java.nio.*;
public class Consumer extends Thread implements Runnable{
private Buffer sharedBuf; // the buffer is the same buffer used by the producer
int sum = 0; // total stuff read from the buffer
//..constructor should accept(Buffer), and set it to the sharedBuf ...
public Consumer (Buffer sharedBuf){
this.sharedBuf=sharedBuf;
}
public void threadRun() throws InterruptedException {
try{
// read the buffer four times, and keep the total
for (int i=1; i<=4; i++)
{
sleep(1);
sum = sum + sharedBuf.get();
}
}
catch(InterruptedException exception) {
exception.printStackTrace();
}
System.out.println("Consumer finished, ate " + sum + "exiting...");
}
}
public class test {
public static void main(String args[]) {
Buffer shared = new Buffer();
Thread a=new Thread( new Producer(shared));
a.start();
Thread b=new Thread( new Consumer(shared));
b.start();
}
}
Thanks for the help once again hope that any one can help me get the output of this program....
Message was edited by: forgot to add my main part of the program .....
liveurlife
public class Producer extends Thread implements Runnable
Dont extend Thread, only implement Runnable. Then, in your main method you want this:
Thread t = new Thread(new Producer(shared));
t.start();
> public class Producer extends Thread implements
> Runnable
> Dont extend Thread, only implement Runnable. Then,
> in your main method you want this:
> Thread t = new Thread(new Producer(shared));
> t.start();
ah, you spotted your error just in time :-)
> ah, you spotted your error just in time :-);-)Also, I dont see a run() method in either of your classes. I might just be tired though (I just woke up).
> Also, I dont see a run() method in either of your
> classes. I might just be tired though (I just woke
> up).
Thanks, I got the answer now, it turns out that i wasnt impmenting the
run() methode correctly, but its fixed now. BTW, I didnt remove the "extends Thread" part, because it only worked when it was there, otherwise my sleep() methode wouldnt work ;)
Thanks once again,
liveurlife
> otherwise my sleep()> methode wouldnt work ;)Thread.currentThread().sleep(/* amount here */);You can do that. You really shouldnt extend Thread and implement Runnable.
> > Also, I dont see a run() method in either of your
> > classes. I might just be tired though (I just
> woke
> > up).
>
> Thanks, I got the answer now, it turns out that i
> wasnt impmenting the
> run() methode correctly, but its fixed now. BTW, I
> didnt remove the "extends Thread" part, because it
> only worked when it was there, otherwise my sleep()
> methode wouldnt work ;)
>
> Thanks once again,
>
> liveurlife
what sleep() method? I'm almost certain you're not doing what you think with it, what is it?
> > otherwise my sleep()
> > methode wouldnt work ;)
>
> Thread.currentThread().sleep(/* amount here
> */);
> You can do that. You really shouldnt extend Thread
> and implement Runnable.
sleep is a static method. no need to - and no effect from - invoking it on a particular thread instance
> sleep is a static method.Wow, I never knew that!
> > sleep is a static method.> > Wow, I never knew that!every day's a school day :)
> > otherwise my sleep()
> > methode wouldnt work ;)
>
> Thread.currentThread().sleep(/* amount here
> */);
> You can do that. You really shouldnt extend Thread
> and implement Runnable.
Ohh coo00ool, I never really knew that I can do that before....its the 1st time im working with threads. I changed it in my code and its working in the same way. thank you :)
Hi,
I've just been going through my code and the output, my threads are working properly, but, i dont think that they're doing what they are supposed to be, because the consumer is eating 10, and it shouldnt be......can you give me a clue to why it keeps doing that?
this is the output:
Writing1
Reading1
Writing2
Reading2
Writing3
Reading3
Writing4
Producer finished, exiting...
Reading4
Consumer finished, ate 10exiting...
thanks once again
no idea what state your code is in now. post it as-is
this my code:
import java.nio.*;
public class Buffer {
private int buffer = -1;
public void set(int val)
{
System.out.println("Writing" + val);
buffer = val;
}
public int get()
{
System.out.println("Reading" + buffer);
return buffer;
}
}
import java.lang.*;
import java.nio.*;
public class Producer implements Runnable{
private Buffer sharedBuf; // the buffer is the buffer class above
// constructor should accept (Buffer), and set it to the sharedBuf ...
public Producer (Buffer sharedBuf){
this.sharedBuf=sharedBuf;
}
public void run()
{
try{
for (int i=1; i<=4; i++)
{
Thread.currentThread().sleep(3); //sleep for a random time, between 0-3 seconds for example;
sharedBuf.set(i);
}
}
catch (InterruptedException exception) {
exception.printStackTrace();
}
System.out.println("Producer finished, exiting...");
}
}
import java.lang.*;
import java.nio.*;
public class Consumer implements Runnable{
private Buffer sharedBuf; // the buffer is the same buffer used by the producer
int sum = 0; // total stuff read from the buffer
//..constructor should accept(Buffer), and set it to the sharedBuf ...
public Consumer (Buffer sharedBuf){
this.sharedBuf=sharedBuf;
}
public void run() {
try{
// read the buffer four times, and keep the total
for (int i=1; i<=4; i++)
{
Thread.currentThread().sleep(3);
sum = sum + sharedBuf.get();
}
}
catch(InterruptedException exception) {
exception.printStackTrace();
}
System.out.println("Consumer finished, ate " + sum + "exiting...");
}
}
public class test {
public static void main(String args[]) {
Buffer shared = new Buffer();
Thread t=new Thread( new Producer(shared));
t.start();
Thread b=new Thread( new Consumer(shared));
b.start();
}
}
This is the output:
Writing1
Reading1
Writing2
Reading2
Writing3
Reading3
Writing4
Producer finished, exiting...
Reading4
Consumer finished, ate 10exiting...
Thanks in advance...
sleep works in milliseconds, not seconds. that's probably itignore this :)Message was edited by: georgemc
4 + 3 + 2 + 1 = 10What are you expecting it to do? You set 1, then eat 1. You set 2, then eat 2, etc.
Shouldn't the reading/writing of the Buffer be synchronized? It happens to be coming out in the right order in the OP's output, but that isn't guaranteed without proper synchronization.
> 4 + 3 + 2 + 1 = 10
> What are you expecting it to do? You set 1, then eat
> 1. You set 2, then eat 2, etc.
I have to make sure that this doesnt happen....what i did is that i made the producer make stuff, and then i made the consumer eat it directly.
I kind of want them to be "un-synchronized", i just want to let the producers and consumers do their stuff. But the problem is that i dont really know how i can do that...........
> I have to make sure that this doesnt happen....what i
> did is that i made the producer make stuff, and then
> i made the consumer eat it directly.
> I kind of want them to be "un-synchronized", i just
> want to let the producers and consumers do their
> stuff. But the problem is that i dont really know
> how i can do that...........
You still havent made yourself clear. Try posting some output that you are expecting.
If you change your 'sleep' calls so they aren't the same [not both '3' (and, you still have the unnecessary "currentThread()" there)], and/or let it run for more than 4 set/get calls (change the 'for' loops to go to something higher than 4), you're less likely to get a simple sequence with the consumer eating everything the producer makes immediately. And, you will get a random sum, depending on how far ahead of the consumer the producer gets.
I reread your original post. I guess the point of the program is to show what happens without synchronization. In that case, try what I said: change the sleep lengths, and run for a longer period of time.
Another couple of questions:
Why are you importing java.nio.*? Are you supposed to use (extend, since it is abstract) a java.nio.Buffer?
What is the "wakeup" method? You haven't handled any "full" or "empty" conditions. I think it means:
You can't "set" the buffer if it is full. You can't "get" from the buffer if it is empty.
==============
Also, you don't need to import java.lang.*. You have access to those classes without an import.
Basically your entire logic is flawed as this wouldnt come out with proper output everytime.You need to synchronize the context switch and the production and consumption between the 2 threads.
> You need to synchronize...He doesn't want it to be synchronized.
> > You need to synchronize...
>
> He doesn't want it to be synchronized.
Then the OP can never be assured that the producer consumer problem would work the right way.It would just result in consumer retrieving duplicate values.And moreover it would also result in consumer retrieving junk value if the consumer is alloted a cpu cycle initially before the producer is assigned any.The OP needs to satisfy the constraints set by the producer consmer roblem which is absolutely missing here
> > > You need to synchronize...
> >
> > He doesn't want it to be synchronized.
>
> Then the OP can never be assured that the producer
> consumer problem would work the right way.It would
> just result in consumer retrieving duplicate
> values.And moreover it would also result in consumer
> retrieving junk value if the consumer is alloted a
> cpu cycle initially before the producer is assigned
> any.The OP needs to satisfy the constraints set by
> the producer consmer roblem which is absolutely
> missing here
The OP's assignment is apparently intended to do just that: show what happens without synchronization. Read more carefully (I didn't read it at first, but later corrected myselfyou just keep coming up with bad advice for the assignment).
> Why are you importing java.nio.*? Are you supposed
> to use (extend, since it is abstract) a
> java.nio.Buffer?
>
I imported the java.nio.*, because i was extending before and implementing runnable at the same time. But then I was advised not to use them together (extend + runnable) so i took extend out and I forgot to take out that part. But no, i dont have to use extend.
> What is the "wakeup" method?
As for the wakeup methode I have no idea about how im supposed to use it. I dont think that I'l need it because my program is running fine without it. i think its the execution will continue normally without me having to wake it up
manually.
BTW to make my threads un-sychronized i used this in my consumer/producer parts of my code :
int random = (int)(Math.random() * 3000);
Thread.currentThread().sleep(random);
instead of this:
Thread.currentThread().sleep(3);
Thanks for all your help :)
You're welcome for the help.
Don't forget: You don't need currentThread() for sleep. You should just call:
Thread.sleep(random);
You could use the nextInt in java.util.Random:
Random randGenerator = new Random(); // Once, at the beginning.
Thread.sleep(randGenerator.nextInt(3000)); // When it's time to sleep.
> You're welcome for the help.
>
> Don't forget: You don't need currentThread() for
> sleep. You should just call:
>
> Thread.sleep(random);
>
> You could use the nextInt in java.util.Random:
> Random randGenerator = new Random(); // Once,
> at the beginning.
>
> Thread.sleep(randGenerator.nextInt(3000)); // When
> it's time to sleep.
thanks for the tips....I'l try them out ;)