Reputation: 145
My code is:
public class Application {
public static void main(String args[]) throws InterruptedException{
Fifo f = new Fifo();
Producer pr = new Producer("elso",f);
pr.go();
Thread.sleep(2000);
Consumer cr = new Consumer("csacsi",f,1000);
cr.start();
}
}
public class Producer extends Thread{
String szoveg;
int szam;
Fifo ff;
Producer(String s, Fifo f){ ff = f; szoveg =s; szam = 0; }
public void go(){
start();
}
public void run(){
while(szam<6)
try {
sleep(1000);
ff.put(szoveg+ " "+szam);
System.out.println("producer" +" " +ff.get()+" "+System.currentTimeMillis()%100000);
//System.out.println(szoveg +" "+ szam+ " "+System.currentTimeMillis()%100000);
szam++;
} catch (InterruptedException e) {
System.out.println("fasz");
}
//szam+=1;
}
}
import java.util.ArrayList;
public class Fifo {
ArrayList<String> str = new ArrayList<String>();
synchronized void put(String s) throws InterruptedException{
while(str.size()>9){
//Thread.sleep(10);
}
str.add(s);
}
String get() throws InterruptedException{
synchronized(str){
if(str.size()==0) str.wait();
if(str.size()!=0) str.notifyAll();
//Thread.sleep(10);
String s = str.get(0);
str.remove(0);
return s;}
}
}
public class Consumer extends Thread{
Fifo F;
String S;
int I,asd;
Consumer (String s, Fifo f, int i){
F=f; S=s; I=i;
}
public void run(){
while(asd<6){
try {
sleep(I);
System.out.println("consumer "+F.get());
asd++;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
and the outputs:
producer elso 0 34491
producer elso 1 35493
producer elso 2 36493Exception in thread "Thread-1"
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at alap.Fifo.get(Fifo.java:24)
at alap.Consumer.run(Consumer.java:16)
producer elso 3 37495
producer elso 4 38496
producer elso 5 39496
So, what is my mistake?
Upvotes: 0
Views: 3340
Reputation: 33083
When you use synchronized
, you need to synchronize on the exact same instance in both threads that should be protected from each other, otherwise it won't have the desired effect.
Your put
method is synchronizing on this
, whereas your get
method is synchronizing on str
, and those are two different objects, so it doesn't have the necessary protective effect.
Upvotes: 1