简体   繁体   English

Java线程notify()wait()用于更快的计算

[英]Java threads notify() wait() for faster calculation

I must create simple application with threads. 我必须使用线程创建简单的应用程序。 Task: faster calculation than serial processing. 任务:比串行处理更快的计算。 I must use methods notify( ) or notifyAll() , wait() , interrupt() and operator synchronized . 我必须使用方法notify( )或notifyAll()wait()interrupt()和操作符synchronized I tried solve this by example from book. 我试图通过书中的例子解决这个问题。 This example is typical producent consumer task. 此示例是典型的生产消费者任务。 But parallel threads calculating is slower then serial. 但是并行线程的计算要慢于串行线程。

Class with notify() , wait() and 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;
    }
  }
}

Producer class: 生产者类别:

public class Producent extends Thread {
    private Reader reader;

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

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

Consumer class: 消费类:

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;
    }
}

And main class code (I know that I can create objects in cycles for bigger comfort but this is only example): 和主类代码(我知道我可以为更舒适地循环创建对象,但这仅是示例):

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);
    }
}

}

When I run this program, serial computing is much faster than parallel. 当我运行该程序时,串行计算比并行处理要快得多。 But I have dual core and I thing that parallel calculation must be faster. 但是我有双核,我认为并行计算必须更快。 I am not experienced in threads and maybe my example is dummy...Please, where can be a problem? 我没有线程方面的经验,也许我的例子是虚拟的。。。请问哪里有问题? Thanks 谢谢

If you want faster execution using Threads, I think that you should use a single class that will accomplish the same thing as serial, something like that : 如果您想使用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;
    }
}

In this way, parallel computing is 2 times faster than serial coputing. 这样,并行计算的速度是串行计算速度的2倍。 I think the pattern Producer-Consummer you applied can't be faster than serial because you make way more instructions and breaks in the code by : 我认为您使用的Producer-Consummer模式不能比串行模式快,因为您可以通过以下方式使更多指令和代码中断:

  1. Getting a new value (Consumer waits a new item to be available) 获取新值(消费者等待新商品可用)
  2. Using this value (Producer waits consummer to finish its calculation) 使用此值(生产者等待消费者完成其计算)

Maybe the producer should be the one who generates random number, and the consummer the one using these values ? 也许生产者应该是生成随机数的人,而消费者应该是使用这些值的人?

(And please use while(isRead) and ! operator for the contrary instead of those ugly while(isRead == false) : this is more readable ;)) (并且请相反使用while(isRead)!运算符,而不要使用丑陋的while(isRead == false) :这更易读;))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM