我的代码是:
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();
}
}
}
}
和输出:
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
那么,我的错误是什么?
答案 0 :(得分:1)
当你使用synchronized
时,你需要在两个线程中完全相同的实例上进行同步,这些实例应该相互保护,否则就不会产生预期的效果。
您的put
方法正在this
上进行同步,而您的get
方法正在str
进行同步,这些是两个不同的对象,因此它没有必要的保护作用。