最近在写一个并行程序来解线性方程组,但是发现运行后比串行的速度还慢,而且不止慢一点点.差不多是慢了5倍的样子.想问两个问题:
1.java线程有支持多核吗.JDK1.5
2.可以查看正在运行中的线程是由哪个处理器运行的吗?也很有可能是我的程序写得有问题,我正在检查.不知道各位是不是也碰到过同样的情况,有什么经验可以分享下吗.谢谢啦

解决方案 »

  1.   

    有个疑问:Java程序在多核环境下运行和单核环境下有什么差异呢?~
      

  2.   

    没什么特别的,我能想到的唯一特别的就是CPU的占用率,多核在这方面肯定占优势
      

  3.   

    我也想问,java的多线程在多核环境下运行,会比单核下运行快么?
    如果在同一时刻,有多个线程并行运行,那jdk里关于现成操作的方法是不是就没用了呢?
      

  4.   

    在计算过程中我使用的是LU分解方法,L,U二维数组都是共享资源.我觉得这个很像是生产者消费者问题,当消费者需要的资源不符合他的要求的时候就会让出锁给生产者,使用wait().但是现在就有个问题,下面是我的共享二维数组类:
    public class Matrix {
        double matrix[][];
        int n;
        /**
         *构造函数
         *根据标志flag的不同初始化U或L
         **/
        public Matrix(String flag,int n) {
         this.n=n;
         matrix=new double[n][n];
         int i,j,k;
         //对U做初始化,上三角的每个元素置-0.0000001代表没有赋值
         if(flag.equalsIgnoreCase("u")){
         for(i=0;i<n;i++){
         for(j=i;j<n;j++){
         matrix[i][j]=-0.0000001;
         }
         }
         //对L做初始化,下三角的每个元素置-0.0000001代表没有赋值
         }else if(flag.equalsIgnoreCase("l")){
         for(i=0;i<n;i++){
         for(j=0;j<i+1;j++){
         matrix[i][j]=-0.0000001;
         }
         }
             for(j=0;j<n;j++){
          matrix[j][j]=1;
        }
           }
        } 
        //并行计算时使用,达到同步的目的 
        public synchronized double get(int i,int j){
         while(matrix[i][j]==-0.0000001){
         try{
          this.wait();
         }catch(InterruptedException e){
         System.out.println(e.getMessage());
         }
         }
         return matrix[i][j];
        
        }    
    //并行计算时使用,达到同步的目的 
        public synchronized void set(int i,int j,double value){
         this.notify();
         matrix[i][j]=value;
        }
    }
    问题在get方法.因为我要检查的是数组中某个单元的值是否符合要求,但是set方法中赋值的单元不一定是get方法中想得到的单元,所以在get方法中需要一直在等待.所以我用了一个循环,我想应该是这个地方占了很多时间.但是怎么解决呢.
      

  5.   

       public synchronized void set(int i,int j,double value){ 
        matrix[i][j]=value; 
        this.notify(); 
        } 你贴的代码不够分析的,不知道谁调用了set ,也就是说不知道什么情况下会notify 另外这例子不适合做多线程demo。
      

  6.   

       matrix[i][j]=value; 
        this.notify(); 
    这两句的顺序应该没有问题.我把其他代码贴出来大家看看.
    除了上面的 Matrix外,还有三个类:CL,CU两个线程,负责进行LU分解,CLU主程序.public class CL implements Runnable{
         int n;
        double a[][];
        Matrix l;
        Matrix u;
         
         public CL(int n,double a[][],Matrix l,Matrix u){
            this.n=n;
            this.a=a;
            this.l=l;
            this.u=u;
         }
         public void run(){
          System.out.println("CL BEGIN");
            for(int i=0;i<n;i++){
              for(int j=i+1;j<n;j++){
                int k=0;
                for(int m=0;m<i;m++){
                     double temp=u.get(m,i);
                     k+=l.get(j,m)*temp;
                   }
                double temp2=u.get(i,i);
                l.set(j,i,(a[j][i]-k)/temp2);
              }
                      //System.out.println(l.toString());

            }
            CLU.flagL=true;
            System.out.println("CL END");
    //        System.out.println(l.toString());
         }

    }
    public class CU implements Runnable{
      int n;
      double a[][];
      Matrix l;
      Matrix u;
         
         public CU(int n,double a[][],Matrix l,Matrix u){
            this.n=n;
            this.a=a;
            this.l=l;
            this.u=u;
         }
      
      public void run(){
       System.out.println("CU BEGIN");
        for(int i=0;i<n;i++){
          for(int j=i;j<n;j++){
            int k=0;
            for(int m=0;m<i;m++){
               double temp=l.get(i,m);
                  k+=temp*u.get(m,j);
                  //Thread.yield();
            }
            u.set(i,j,a[i][j]-k);
          }
          //System.out.println(u.toString());
        }
        CLU.flagU=true;
        System.out.println("CU END");
    //    System.out.println(u.toString());
      }
      
    }
    class CLU{

        double a[][];
        Matrix l;
        Matrix u;
        static boolean flagL;
        static boolean flagU;
         int n;  //线性方程的阶数
    public CLU(double matrixA[][]){
    this.a=matrixA;
    this.n=a.length;
    u=new Matrix("u",n);
    l=new Matrix("l",n);
    }
    //并行计算L和U
    public void caculateLU(){
    CL cu=new CL(n,a,l,u);
    CU cl=new CU(n,a,l,u);
    Thread tu=new Thread(cu);
    Thread tl=new Thread(cl); tu.start();
    tl.start(); while(!(flagL&&flagU)){

    }

    }

    //串行计算L和U
    /**
     *算法,做n次循环,没次循环中先算U的i行,再在U的i行基础上算L的i列
     */
    public void caculateLU_s(){
    int i,j,k,m;
    double temp;  for(i=0;i<n;i++){
     //计算U的第i行
          for(j=i;j<n;j++){
            k=0;
            for(m=0;m<i;m++){
               temp=l.get_s(i,m);
               k+=temp*u.get_s(m,j);
            }
            u.set_s(i,j,a[i][j]-k);
          }
          //计算L的第i列
           for(j=i+1;j<n;j++){
                k=0;
                for(m=0;m<i;m++){
                     temp=u.get_s(m,i);
                     k+=l.get_s(j,m)*temp;
                   }
                double temp1=u.get_s(i,i);
                l.set_s(j,i,(a[j][i]-k)/temp1);
              }             
       }

    }
    public static void main(String a[]){
            int n=100;
            double matrixa[][]=new double[n][n];
            int i,j;
            for(i=0;i<n;i++)
              for(j=0;j<n;j++)
                 matrixa[i][j]=i+j+1;
        CLU clu=new CLU(matrixa);
            System.out.println(new java.util.Date());
    clu.caculateLU();//并行
    //clu.caculateLU_s();//串行
        System.out.println(new java.util.Date()); System.out.println(clu.x.toString());
    }

    }
      

  7.   

    public class CL implements Runnable{
         int n;
        double a[][];
        Matrix l;
        Matrix u;
         
         public CL(int n,double a[][],Matrix l,Matrix u){
            this.n=n;
            this.a=a;
            this.l=l;
            this.u=u;        
         }
         public void run(){
             System.out.println("CL BEGIN");
            for(int i=0;i<n;i++){
              for(int j=i+1;j<n;j++){
                int k=0;
                for(int m=0;m<i;m++){
                     double temp=u.get(m,i);
                     k+=l.get(j,m)*temp;
                   }
                double temp2=u.get(i,i);
                l.set(j,i,(a[j][i]-k)/temp2);
              }
                      //System.out.println(l.toString());
        
            }
            CLU.flagL=true;    
            System.out.println("CL END");
    //        System.out.println(l.toString());
         }
        
    }
    Java code
    public class CU implements Runnable{
      int n;
      double a[][];
      Matrix l;
      Matrix u;
         
         public CU(int n,double a[][],Matrix l,Matrix u){
            this.n=n;
            this.a=a;
            this.l=l;
            this.u=u;        
         }
      
      public void run(){
          System.out.println("CU BEGIN");
        for(int i=0;i<n;i++){
          for(int j=i;j<n;j++){
            int k=0;
            for(int m=0;m<i;m++){
               double temp=l.get(i,m);
                  k+=temp*u.get(m,j);
                  //Thread.yield();    
            }
            u.set(i,j,a[i][j]-k);
          }
          //System.out.println(u.toString());    
        }
        CLU.flagU=true;    
        System.out.println("CU END");
    //    System.out.println(u.toString());
      }
      
    }
    Java code
    class CLU{
        
        double a[][];
        Matrix l;
        Matrix u;
        static boolean flagL;
        static boolean flagU;
         int n;  //线性方程的阶数
        public CLU(double matrixA[][]){
            this.a=matrixA;
            this.n=a.length;
            u=new Matrix("u",n);
            l=new Matrix("l",n);
        }
        //并行计算L和U
        public void caculateLU(){
            CL cu=new CL(n,a,l,u);
            CU cl=new CU(n,a,l,u);
            Thread tu=new Thread(cu);
            Thread tl=new Thread(cl);        tu.start();
            tl.start();        while(!(flagL&&flagU)){
                
            }
            
        }
        
        //串行计算L和U
        /**
         *算法,做n次循环,没次循环中先算U的i行,再在U的i行基础上算L的i列
         */
        public void caculateLU_s(){
        int i,j,k,m;
        double temp;     for(i=0;i<n;i++){
         //计算U的第i行
          for(j=i;j<n;j++){
            k=0;
            for(m=0;m<i;m++){
               temp=l.get_s(i,m);
               k+=temp*u.get_s(m,j);
            }
            u.set_s(i,j,a[i][j]-k);
          }
          //计算L的第i列
           for(j=i+1;j<n;j++){
                k=0;
                for(m=0;m<i;m++){
                     temp=u.get_s(m,i);
                     k+=l.get_s(j,m)*temp;
                   }
                double temp1=u.get_s(i,i);
                l.set_s(j,i,(a[j][i]-k)/temp1);
              }                   
           }    
        
        }
        public static void main(String a[]){
            int n=100;
            double matrixa[][]=new double[n][n];
            int i,j;
            for(i=0;i<n;i++)
              for(j=0;j<n;j++)
                 matrixa[i][j]=i+j+1;
               CLU clu=new CLU(matrixa);
            System.out.println(new java.util.Date());
            clu.caculateLU();//并行
            //clu.caculateLU_s();//串行
            System.out.println(new java.util.Date());    System.out.println(clu.x.toString());
        }
        
    }
      

  8.   

    可以啊,有两种方法,一种是jconsole
    一种是线程包里有个函数