尝试使用生产者和消费者模式打印斐波那契数列

trying to print a Fibonacci series using producer and consumer pattern

我希望能够使用线程打印斐波那契数列,所以我创建了 2 个线程:

生产者将根据公式 f(n) = f(n-1)+f(n-2) 填充数组 将打印到目前为止已计算的元素的消费者

我会将共享数组设置为一次只能存储5个元素,消费者将释放数组中的space,让生产者添加更多元素。

这是我的消费者代码:

public class Consumer implements Runnable
{
    private LinkedList<Integer> sharedArray;

public Consumer(LinkedList<Integer> array, int size, int series)
{
    sharedArray = array;

}

@Override
public void run()
{
    while (true)
    {
        try
        {
            print();
        } catch (InterruptedException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

private void print() throws InterruptedException
{
    while (true)
    {
        synchronized (sharedArray)
        {
            while (sharedArray.isEmpty())
            {
                try
                {
                    sharedArray.wait();
                } catch (Exception ex)
                {
                    ex.printStackTrace();
                }

            }
            System.out.print(sharedArray.get(0) + " ");
            sharedArray.notifyAll();
        }

    }
}

}

这是生产者代码:

public class Producer implements Runnable

{
private LinkedList<Integer> sharedArray;
private int sharedArraySize;
private int seriesSize;

public Producer(LinkedList<Integer> array, int size, int series)
{
    sharedArray = array;
    sharedArraySize = size;
    seriesSize = series;

}

@Override
public void run()
{
    for (int i = 0; i < seriesSize; i++)
    {
        try
        {
            calculate(i);
        } catch (InterruptedException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

private void calculate(int n) throws InterruptedException
{
    synchronized (sharedArray)
    {
        while (sharedArray.size() == sharedArraySize)
        {
            sharedArray.wait();
        }
        if (n == 0 || n == 1)
        {
            sharedArray.add(n, 1);
        } else
        {
            sharedArray.add(n, sharedArray.get(n - 1) + sharedArray.get(n - 2));
        }
        sharedArray.notifyAll();
    }
}

}

和启动两个线程的主要 class:

public class FibThreads

{


public static void main(String[] args)
{
    int seriesSize = 18; //Integer.parseInt(args[0]);
    int elementsInLine = 0;//Integer.parseInt(args[1]);
    int sharedArraySize = 5;//Integer.parseInt(args[2]);

    LinkedList<Integer> sharedArray = new LinkedList<Integer>();

    Thread producer = new Thread(new Producer(sharedArray,sharedArraySize,seriesSize), "Producer");
    Thread consumer = new Thread(new Consumer(sharedArray,sharedArraySize,seriesSize), "Consumer");
    producer.start();
    consumer.start();
    System.out.println("End of main");
}

}

我的问题是: 在尝试 运行 这个之后,我得到了一个无限循环,因为一旦数组中有一个新项目,消费者拿走它并释放 space,这意味着数组不能真正填充项目,因为消费者会立即释放它。 我怎样才能让它发挥作用?

只有“1”输出的新问题是因为 .get()peekFirst 一样,您得到了第一个元素,但它没有删除它!

我假设您想要的是 System.out.print(sharedArray.pollFirst() + " ");,它检索第一个元素并将其从链表中删除。

你的错误可能是因为你删除了一个节点,但你没有在你的生产者中更新 n 然后指向错误的索引,因为每个删除的元素应该是 -1。

编辑:您还应该检查的是您的消费者没有删除所有元素,因为您至少需要 2 个元素来计算下一个斐波那契数!

编辑 2: 类似于

while (sharedArray.isEmpty()||sharedArray.size()<=2)
            {
                try
                {
                    sharedArray.wait();
                } catch (Exception ex)
                {
                    ex.printStackTrace();
                }

            }...

并且您需要在您的生产者中更新 N,您可以将其更改为 sharedArray.add(sharedArray.size(),sharedArray.size()-1+sharedArray.size()-2); 这样您就永远不会出界。 您可以这样做,因为您已经事先检查是否达到了限制并且根本不需要 n

编辑 3:

sharedArray.add(sharedArray.size(),sharedArray.size()-1+sharedArray.size()-2);

应该是

sharedArray.add(sharedArray.size(),sharedArray.get(sharedArray.size()-1)+sharedArray.get(sharedArray.size()-2));

我的错应该提到....