0

私のコードは次のとおりです。

 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

それで、私の間違いは何ですか?

4

1 に答える 1

1

を使用する場合synchronized、相互に保護する必要がある両方のスレッドのまったく同じインスタンスで同期する必要があります。そうしないと、目的の効果が得られません。

putメソッドは で同期してthisいますが、getメソッドは で同期していますstrが、これらは 2 つの異なるオブジェクトであるため、必要な保護効果がありません。

于 2013-10-26T19:24:02.713 に答える