Java 尝试使用生产者和消费者模式打印斐波那契数列
我希望能够使用线程打印斐波那契数列,因此我创建了两个线程: 根据公式f(n)=f(n-1)+f(n-2)填充数组的生产者 将打印到目前为止已计算的元素的使用者 我将把共享数组设置为一次只能存储5个元素,使用者将释放数组中的空间,允许生产者添加更多元素 这是我的消费代码:Java 尝试使用生产者和消费者模式打印斐波那契数列,java,multithreading,synchronization,producer-consumer,Java,Multithreading,Synchronization,Producer Consumer,我希望能够使用线程打印斐波那契数列,因此我创建了两个线程: 根据公式f(n)=f(n-1)+f(n-2)填充数组的生产者 将打印到目前为止已计算的元素的使用者 我将把共享数组设置为一次只能存储5个元素,使用者将释放数组中的空间,允许生产者添加更多元素 这是我的消费代码: public class Consumer implements Runnable { private LinkedList<Integer> sharedArray; public Consumer(Li
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();
}
}
}
}
公共类使用者实现可运行
{
私有LinkedList sharedArray;
公共使用者(LinkedList数组、整数大小、整数系列)
{
sharedArray=数组;
}
@凌驾
公开募捐
{
while(true)
{
尝试
{
打印();
}捕捉(中断异常e)
{
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}
private void print()引发InterruptedException
{
while(true)
{
已同步(sharedArray)
{
while(sharedArray.isEmpty())
{
尝试
{
sharedArray.wait();
}捕获(例外情况除外)
{
例如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();
}
}
}
公共类生成器实现可运行
{
私有LinkedList sharedArray;
私有整数共享DarraySize;
私有int系列化;
公共生产者(LinkedList数组、整数大小、整数系列)
{
sharedArray=数组;
sharedarray大小=大小;
系列化=系列化;
}
@凌驾
公开募捐
{
for(int i=0;i
以及启动两个线程的主类:
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");
}
}
public类线程
{
公共静态void main(字符串[]args)
{
int seriesSize=18;//Integer.parseInt(args[0]);
int-elementsInLine=0;//Integer.parseInt(args[1]);
int sharedaraysize=5;//Integer.parseInt(args[2]);
LinkedList sharedArray=新建LinkedList();
线程生成器=新线程(新生成器(sharedArray、sharedArraySize、seriesSize),“生成器”);
线程消费者=新线程(新消费者(sharedArray、sharedArraySize、seriesSize),“消费者”);
producer.start();
consumer.start();
System.out.println(“主管道末端”);
}
}
我的问题是:尝试运行此操作后,我得到了一个无限循环,因为一旦数组中有新项目,消费者就会获取它并释放空间,这意味着数组不能真正充满项目,因为消费者会立即释放它。
如何使它工作?您唯一的“1”输出的新问题是因为
.get()
与peekFirst
一样,您获得了第一个元素,但它没有删除它
我假设您想要的是System.out.print(sharedArray.pollFirst()+)代码>,它检索第一个元素并将其从链表中删除
您的错误可能是因为您删除了一个节点,但没有更新producer中的n
,然后该节点指向了错误的索引,因为对于每个删除的元素,它应该是-1
编辑:您还应该检查您的消费者没有删除所有元素,因为您需要至少2个元素来计算下一个斐波那契数
编辑2:类似
while (sharedArray.isEmpty()||sharedArray.size()<=2)
{
try
{
sharedArray.wait();
} catch (Exception ex)
{
ex.printStackTrace();
}
}...
while(sharedArray.isEmpty()| | sharedArray.size()你能提供完整代码的链接吗?给定的细节有点困难错误信息会很好,感觉代码丢失了。编辑并添加了我的所有代码。实际上现在没有错误,只是一个无休止的循环。我得到的只是“1…”@wannabeprogrammer这是因为peekfirst不删除第一个元素,所以它将始终是1这正是我的问题,我的消费者清空列表。我如何修复它?想法?一旦我将其更改为pollFirst(),这就是我的错误:线程“Producer”中的异常1 1 java.lang.IndexOutOfBoundsException:Index:1,Size:0位于java.util.LinkedList.checkElementIndex(未知源)位于java.util.LinkedList.get(未知源)位于Producer.calculate(Producer.java:46)位于Producer.run(Producer.java:24)位于java.lang.Thread.run(未知源)我很难理解如何在制作人中更新右ncode@wannabeprogrammer再次更新,希望足够清楚:)谢谢,在你建议的更改后,我的输出是1 1 3 5 1 3 5 1 3 5