gpt4 book ai didi

Java线程notify() wait()以加快计算速度

转载 作者:行者123 更新时间:2023-12-01 13:36:48 27 4
gpt4 key购买 nike

我必须使用线程创建简单的应用程序。任务:比串行处理更快的计算。我必须使用方法 notify() 或 notifyAll()wait()interrupt() 和运算符 同步。我尝试通过书中的例子来解决这个问题。这个例子是典型的生产者消费者任务。但并行线程计算速度比串行慢。

具有 notify()wait()synchronized 的类:

public class Reader {
private boolean isRead = false;
private boolean isFileEnd = false;
private int value;
private int[] pole;
private int pocitadlo=0;

public Reader(int[]pole) {
this.pole=pole;
}

synchronized public void loadValue() {
while (isRead == true) {
try {
wait();
}
catch (InterruptedException e) { }
}


if (pocitadlo<pole.length) {
value = pole[pocitadlo];
pocitadlo++;
}
else {
isFileEnd = true;
Thread.currentThread().interrupt();
}

isRead = true;
notifyAll();
}

synchronized public int getValue() {
while (isRead == false) {
try {
wait();
}
catch (InterruptedException e) { }
}
isRead = false;
if (isFileEnd == false) {
notifyAll();
return value;
}
else {
Thread.currentThread().interrupt();
return 0;
}
}
}

生产者类别:

public class Producent extends Thread {
private Reader reader;

public Producent(Reader reader) {
this.reader = reader;
}

@Override
public void run() {
while (interrupted() == false) {
reader.loadValue();
}
}
}

消费者阶层:

public class Konzument extends Thread {
private Reader reader;
private double sum = 0;

public Konzument(Reader reader) {
this.reader = reader;
}

@Override
public void run() {
int number;
while (true) {
number = reader.getValue();
if (interrupted() == false)
sum += Math.sqrt(number);
else
break;
}
}

public double getSum(){
return sum;
}
}

和主类代码(我知道我可以循环创建对象以获得更大的舒适度,但这只是示例):

public class PARPV2 {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Watch watch=new Watch();
double suma=0;
int size=1000000;
int[]array1=new int[size];
int[]array2=new int[size];
int[]array3=new int[size];
int[]array4=new int[size];
int[]array5=new int[size];

generate(array1);
generate(array2);
generate(array3);
generate(array4);
generate(array5);

Reader reader1=new Reader(array1);
Reader reader2=new Reader(array2);
Reader reader3=new Reader(array3);
Reader reader4=new Reader(array4);
Reader reader5=new Reader(array5);

Producent p1=new Producent(reader1);
Konzument k1=new Konzument(reader1);
Producent p2=new Producent(reader2);
Konzument k2=new Konzument(reader2);
Producent p3=new Producent(reader3);
Konzument k3=new Konzument(reader3);
Producent p4=new Producent(reader4);
Konzument k4=new Konzument(reader4);
Producent p5=new Producent(reader5);
Konzument k5=new Konzument(reader5);

watch.start();

p1.start();
k1.start();
p2.start();
k2.start();
p3.start();
k3.start();
p4.start();
k4.start();
p5.start();
k5.start();
try {


p1.join();
k1.join();
p2.join();
k2.join();
p3.join();
k3.join();
p4.join();
k4.join();
p5.join();
k5.join();

suma=k1.getSum()+k2.getSum()+k3.getSum()+k4.getSum()+k5.getSum();
System.out.println("paralelne: "+watch.stop(false));
System.out.println("suma: "+suma);
} catch (InterruptedException ex) {
Logger.getLogger(PARPV2.class.getName()).log(Level.SEVERE, null, ex);
}
double sum1=0;
double sum2=0;
double sum3=0;
double sum4=0;
double sum5=0;

watch.start();

for (int i = 0; i < array1.length; i++) {
sum1+=Math.sqrt(array1[i]);
}
for (int i = 0; i < array2.length; i++) {
sum2+=Math.sqrt(array2[i]);
}
for (int i = 0; i < array3.length; i++) {
sum3+=Math.sqrt(array3[i]);
}
for (int i = 0; i < array4.length; i++) {
sum4+=Math.sqrt(array4[i]);
}
for (int i = 0; i < array5.length; i++) {
sum5+=Math.sqrt(array5[i]);
}
suma=sum1+sum2+sum3+sum4+sum5;
System.out.println("serial: "+watch.stop(false));
System.out.println("suma: "+suma);
}
public static void generate(int[]array){
Random r=new Random();
for (int i = 0; i < array.length; i++) {
array[i]=r.nextInt(100);
}
}

}

当我运行这个程序时,串行计算比并行计算快得多。但我有双核,我认为并行计算一定更快。我在线程方面没有经验,也许我的例子是虚拟的......请问哪里可能有问题?谢谢

最佳答案

如果您想使用线程更快地执行,我认为您应该使用单个类来完成与串行相同的事情,如下所示:

public class Calc extends Thread {

private int[] array;
private double sum;

public Calc(int[] array) {
this.array = array;
this.sum = 0;
}

@Override
public void run() {
for (int i = 0; i < array.length; i++) {
sum += Math.sqrt(array[i]);
}
}

public double getSum() {
return this.sum;
}
}

这样,并行计算的速度比串行计算快2倍。我认为您应用的生产者-消费者模式不会比串行更快,因为您通过以下方式在代码中创建了更多指令和中断:

  1. 获取新值(消费者等待新商品可用)
  2. 使用该值(生产者等待消费者完成计算)

也许生产者应该是生成随机数的人,而消费者应该是使用这些值的人?

(相反,请使用 while(isRead)! 运算符,而不是那些丑陋的 while(isRead == false) :这更具可读性;))

关于Java线程notify() wait()以加快计算速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21215209/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com