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

[5046 byte] By [liveurlifea] at [2007-11-26 13:22:11]
# 1
Do implement runnable.. it good.do start it like thisThread a=new Thread( new producer());a.start();
G_Abubakra at 2007-7-7 17:52:51 > top of Java-index,Java Essentials,New To Java...
# 2

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

liveurlifea at 2007-7-7 17:52:51 > top of Java-index,Java Essentials,New To Java...
# 3

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();

CaptainMorgan08a at 2007-7-7 17:52:51 > top of Java-index,Java Essentials,New To Java...
# 4

> 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 :-)

georgemca at 2007-7-7 17:52:51 > top of Java-index,Java Essentials,New To Java...
# 5
> 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).
CaptainMorgan08a at 2007-7-7 17:52:51 > top of Java-index,Java Essentials,New To Java...
# 6

> 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

liveurlifea at 2007-7-7 17:52:51 > top of Java-index,Java Essentials,New To Java...
# 7
> otherwise my sleep()> methode wouldnt work ;)Thread.currentThread().sleep(/* amount here */);You can do that. You really shouldnt extend Thread and implement Runnable.
CaptainMorgan08a at 2007-7-7 17:52:51 > top of Java-index,Java Essentials,New To Java...
# 8

> > 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?

georgemca at 2007-7-7 17:52:51 > top of Java-index,Java Essentials,New To Java...
# 9

> > 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

georgemca at 2007-7-7 17:52:51 > top of Java-index,Java Essentials,New To Java...
# 10
> sleep is a static method.Wow, I never knew that!
CaptainMorgan08a at 2007-7-7 17:52:51 > top of Java-index,Java Essentials,New To Java...
# 11
> > sleep is a static method.> > Wow, I never knew that!every day's a school day :)
georgemca at 2007-7-7 17:52:51 > top of Java-index,Java Essentials,New To Java...
# 12

> > 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 :)

liveurlifea at 2007-7-7 17:52:51 > top of Java-index,Java Essentials,New To Java...
# 13

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

liveurlifea at 2007-7-7 17:52:51 > top of Java-index,Java Essentials,New To Java...
# 14
no idea what state your code is in now. post it as-is
georgemca at 2007-7-7 17:52:51 > top of Java-index,Java Essentials,New To Java...
# 15

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...

liveurlifea at 2007-7-21 15:50:20 > top of Java-index,Java Essentials,New To Java...
# 16
sleep works in milliseconds, not seconds. that's probably itignore this :)Message was edited by: georgemc
georgemca at 2007-7-21 15:50:20 > top of Java-index,Java Essentials,New To Java...
# 17
4 + 3 + 2 + 1 = 10What are you expecting it to do? You set 1, then eat 1. You set 2, then eat 2, etc.
CaptainMorgan08a at 2007-7-21 15:50:20 > top of Java-index,Java Essentials,New To Java...
# 18
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.
doremifasollatidoa at 2007-7-21 15:50:20 > top of Java-index,Java Essentials,New To Java...
# 19

> 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...........

liveurlifea at 2007-7-21 15:50:20 > top of Java-index,Java Essentials,New To Java...
# 20

> 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.

CaptainMorgan08a at 2007-7-21 15:50:20 > top of Java-index,Java Essentials,New To Java...
# 21

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.

doremifasollatidoa at 2007-7-21 15:50:20 > top of Java-index,Java Essentials,New To Java...
# 22

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.

doremifasollatidoa at 2007-7-21 15:50:20 > top of Java-index,Java Essentials,New To Java...
# 23
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.
qUesT_foR_knOwLeDgea at 2007-7-21 15:50:20 > top of Java-index,Java Essentials,New To Java...
# 24
> You need to synchronize...He doesn't want it to be synchronized.
CaptainMorgan08a at 2007-7-21 15:50:20 > top of Java-index,Java Essentials,New To Java...
# 25

> > 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

qUesT_foR_knOwLeDgea at 2007-7-21 15:50:20 > top of Java-index,Java Essentials,New To Java...
# 26

> > > 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).

doremifasollatidoa at 2007-7-21 15:50:20 > top of Java-index,Java Essentials,New To Java...
# 27

> 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 :)

liveurlifea at 2007-7-21 15:50:20 > top of Java-index,Java Essentials,New To Java...
# 28

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.

doremifasollatidoa at 2007-7-21 15:50:20 > top of Java-index,Java Essentials,New To Java...
# 29

> 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 ;)

liveurlifea at 2007-7-21 15:50:20 > top of Java-index,Java Essentials,New To Java...