我要斐波那契数列用线打印,数列的第一个数应该用第一个线打印,第二个数用第二个线打印,第三个数用第一个线打印,第四个数用第二个线打印,依此类推。
我使用数组尝试了这段代码,比如使用线程打印数组元素,但是我无法在线程之间切换。
class Fibonacci{
void printFibonacci() {
int fibArray[] = new int[10];
int a = 0;
int b = 1;
fibArray[0] = a;
fibArray[1] = b;
int c;
for(int i=2;i<10;i++) {
c = a+b;
fibArray[i] = c;
a = b;
b = c;
}
for(int i=0;i<10;i++) {
if(Integer.parseInt(Thread.currentThread().getName())%2==0 && (i%2==0))
{
System.out.println("Thread " +Thread.currentThread().getName()+" "+fibArray[i]);
try{
wait();
}catch(Exception e) {}
}
else if(Integer.parseInt(Thread.currentThread().getName())%2!=0 && (i%2!=0))
{
System.out.println("Thread " +Thread.currentThread().getName()+" "+fibArray[i]);
}
}
}
}
public class FibonacciUsingThread {
public static void main(String[] args) throws Exception {
Fibonacci f = new Fibonacci();
Thread t1 = new Thread(()->
{
f.printFibonacci();
});
Thread t2 = new Thread(()->
{
f.printFibonacci();
});
t1.setName("0");
t2.setName("1");
t1.start();
t1.join();
t2.start();
}
}
4条答案
按热度按时间brgchamk1#
作为一种选择,你可以使用一个公平的
Semaphore
在线程和AtomicReference
保持共享状态。举个例子:将打印:
请注意,此解决方案不仅在线程上打印-它还对线程进行实际计算-例如,当轮到线程a时,它使用线程b计算的先前状态来计算下一个斐波那契数。
eiee3dmh2#
代码中的以下行导致
t1
在…之前完成t2
我们可以开始了。除此之外,你需要在方法上同步,
printFibonacci
.您可以按以下步骤进行:
输出:
kqqjbcuj3#
除了以上所说的和已经回答的,我只想为斐波那契序列的实现添加一种替代方法,不使用数组和预先标注尺寸:
仅受数值数据类型(在本例中为整数)溢出的限制。
nfeuvbwi4#
正如“@live and let live”所指出的,代码的主要问题是缺少
synchronized
条款与调用join
在开始第二个线程之前。在我看来,您可以通过首先分离关注点(即类)来稍微清理代码
Fibonacci
只负责计算给定数组的斐波那契:这样,你就可以保持
Fibonacci
类简洁,没有任何线程相关的代码。而且getFibonacci
现在更抽象了;你可以计算fib
而不是像你以前那样的10种元素。然后上课
FibonacciUsingThread
:首先,使用主线程计算fibonaccis,让所有线程计算相同的东西是没有意义的。后来,你指定
Thread 1
以及Thread 2
将分别打印偶数和奇数位置。除非这只是一个使用线程和同步的练习,否则使用线程来完成这类工作没有多大意义。在您的代码中,值得并行化的部分是斐波那契数本身的计算,而不是打印部分。
前面显示的代码不会按顺序打印fibonacci数,因为您需要确保线程在遍历数组的每个元素之后彼此等待。因此,您需要调整将由线程执行的代码,即:
我们可以通过提取一个包含将分配给线程的工作的方法来消除代码冗余。例如:
以及主代码: