我希望能够使用线程打印Fibonacci系列,所以我创建了2个线程:
根据公式f(n)= f(n-1)+ f(n-2)填充数组的生产者 将打印到目前为止已计算的元素的消费者
我将共享数组设置为每次只能存储5个元素,并且使用者将释放数组中的空间,允许生产者添加更多元素。
这是我的消费者代码:
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();
}
}
}
和启动两个线程的主类:
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");
}
}
我的问题是:尝试运行之后,我得到一个无限循环,因为只要数组中有一个新项目,消费者就会获取它并释放空间,这意味着数组不能真正填充项目,因为消费者立即释放它。 我怎样才能使它发挥作用?
答案 0 :(得分:1)
唯一“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);
,这样您就永远不会离开bounderys。
您可以这样做,因为您已经预先检查了是否达到了限制,并且根本不需要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));
我的坏人应该提到......