[英]Java threads notify() wait() for faster calculation
我必須使用線程創建簡單的應用程序。 任務:比串行處理更快的計算。 我必須使用方法notify(
)或notifyAll()
, wait()
, interrupt()
和操作符synchronized
。 我試圖通過書中的例子解決這個問題。 此示例是典型的生產消費者任務。 但是並行線程的計算要慢於串行線程。
具有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);
}
}
}
當我運行該程序時,串行計算比並行處理要快得多。 但是我有雙核,我認為並行計算必須更快。 我沒有線程方面的經驗,也許我的例子是虛擬的。。。請問哪里有問題? 謝謝
如果您想使用Threads更快地執行,我認為您應該使用一個單獨的類,該類將完成與Serial相同的操作,例如:
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倍。 我認為您使用的Producer-Consummer模式不能比串行模式快,因為您可以通過以下方式使更多指令和代碼中斷:
也許生產者應該是生成隨機數的人,而消費者應該是使用這些值的人?
(並且請相反使用while(isRead)
和!
運算符,而不要使用丑陋的while(isRead == false)
:這更易讀;))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.