class MultMatrixPipe implements Runnable
{
   private Thread t;
   private double[][] matrix1;
   private double[][] matrix2;
   private double[][] matrix3;
   private int nThreads, iThread, dim;

   public MultMatrixPipe( double[][] m1, double[][] m2, double[][] m3, int d, int nT )
   {
	  matrix1 = m1;
	  matrix2 = m2;
	  matrix3 = m3;

	  dim = d;
	  nThreads = nT;
      t = new Thread ( this );
   }

   public void calculaCelula( int iT )
   {
      iThread = iT;
      t.start();
   }

   public void run()
   {
	  int nOps = dim/nThreads;
	  int shift = iThread*nOps;
	  for ( int k = 0; k < nOps; ++k )
	  {
		 for ( int i = 0; i < dim; ++i )
		 {
			for ( int j = 0; j < dim; ++j )
			{
			   synchronized(this)
			   {
				  matrix3[i][j] += matrix1[i][k+shift] * matrix2[k+shift][j];
			   }
			}
		 }
	  }
   }

   public void join()
   {
	  try
	  {
		t.join();
	  }
	  catch( InterruptedException e )
	  {
		e.printStackTrace();
	  }
   }
}

class TestePipe
{
   public static void main( String args[] )
   {
      int d = Integer.parseInt(args[0]);
	  int nThreads = Integer.parseInt(args[1]);

      double[][] m1 = new double[d][];
      for ( int i = 0; i < d; ++i )
      {
         m1[i] = new double[d];
         for ( int j = 0; j < d; ++j ) m1[i][j] = (i*d)+j;
      }

      double[][] m2 = new double[d][];
      for ( int i = 0; i < d; ++i )
      {
         m2[i] = new double[d];
         for ( int j = 0; j < d; ++j ) m2[i][j] = (i*d)+j;
      }

      double[][] m3 = new double[d][];
      for ( int i = 0; i < d; ++i )
	  {
		 m3[i] = new double[d];
		 for ( int j = 0; j < d; ++j ) m3[i][j] = 0;
	  }

      long startTime = System.currentTimeMillis();

	  MultMatrixPipe[] m = new MultMatrixPipe[nThreads];
      for ( int i = 0; i < nThreads; ++i )
      {
         m[i] = new MultMatrixPipe(m1, m2, m3, d, nThreads);
         m[i].calculaCelula(i);
      }

	  for ( int i = 0; i < nThreads; ++i ) m[i].join();

      long endTime = System.currentTimeMillis();
      System.out.printf("duration = %f\n", (endTime - startTime)/1000.0);
   }
}
