为什么我的生产者线程没有完成它的任务?

时间:2014-09-26 14:53:08

标签: java multithreading fibonacci

我正在研究Java中的生产者 - 消费者问题,其中生产者在管道中编写Fibonacci数字,消费者通过管道读取器消费它并检查它是否是素数。

问题是只有前3个Fibonacci素数是由下面给出的代码生成的。

它出了什么问题?

package fibonacciprime;
import java.io.*;
import java.lang.*;
public class FibonacciPrime extends Thread {
    public static void main(String[] args) throws Exception {
        //final PipedOutputStream pout=new PipedOutputStream();
        //final PipedInputStream pin=new PipedInputStream();
        final PipedWriter pwriter = new PipedWriter();
        final PipedReader preader = new PipedReader(pwriter);
        //pout.connect(pin);
        Thread threadA=new Thread()
        {
            public void run()
            {
                for(int i=2;i<1000;i++)
                {
                    synchronized(pwriter)
                    {
                        try
                        {
                            int temp=5*i*i-4;
                            int temp1=5*i*i+4;
                            int p=(int)Math.sqrt(temp1)*(int)Math.sqrt(temp1);
                            int q=(int)Math.sqrt(temp)*(int)Math.sqrt(temp);

                            if(p==temp1 || q==temp)
                                pwriter.write(i);

                        }catch(Exception e){e.printStackTrace();}
                    }
                }
                try {
                    pwriter.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };

        Thread threadB = new Thread()
        {
            public void run()
            {
                int flag=0;
                try
                {
                    int temp;
                    while( ( temp = preader.read() ) != -1)
                    {
                        //int k=pin.read();
                        for(int i=2;i*i < temp;i++)
                        {
                            if(temp%i==0)
                            {
                                flag=1;
                                break;
                            }
                        }
                        Thread.sleep(100);
                        if(flag==0)
                            System.out.println(temp);
                    }
                    preader.close();
                }catch(Exception e){e.printStackTrace();}
            }
        };
        threadA.start();
        threadB.start();
    }
}

1 个答案:

答案 0 :(得分:4)

您的生产者线程 正在完成其任务,但您的消费者有错误,因此它不会打印相应的值。

您声明了用于检测while循环之外的素数的标志,并且从不重置其值。因此,一旦读取了第一个非素数(8),那么之后的所有数字都将被视为复合数,即使它们是素数。

你只需要在你的while循环中移动flag的声明,你的程序就可以了:

while ((temp = preader.read()) != -1) {
    int flag = 0;  // moved this to inside the loop
    for (int i = 2; i * i < temp; i++) {
        if (temp % i == 0) {
            flag = 1;
            break;
        }
    }
    Thread.sleep(100);
    if (flag == 0) System.out.println(temp);
}