想问大家一个问题  如何分别用4,128个线程计算两个向量的乘积 每个向量1000个元素 array1=(a1,..a1000), array2=(b1,...b1000) 
P=array1 * array2=a1*b1+...a1000*b1000
最好能给个代码段 
万分感谢 再万分感谢

解决方案 »

  1.   

    例子,可能有错误。 
    能跑出结果 length太大的话可能会 heap 溢出。
    加大内存空间,或者在这个基础上改进一下吧。public class TArray {

    //number of thread
    private static int threadNum = 10;

    //length of array
    private static int arrayLength = 100000;


    public static void main(String args[]){

    TArray service = new TArray();

    int[] a = service.createArray(arrayLength);
    int[] b = service.createArray(arrayLength);


    CalcArray[] calcServ = new CalcArray[threadNum];


    int x = arrayLength / threadNum;
    int idx = 0 ;
    for(int i=0;i<threadNum-1;i++){
    calcServ[i] = new CalcArray(a,b,idx,idx+=x);
    }
    calcServ[threadNum-1] = new CalcArray(a,b,idx,arrayLength-1);

    for(int i=0;i<threadNum;i++){
    calcServ[i].start();
    }



    for(int i=0;i<threadNum;i++){
    try {
    calcServ[i].join();
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }


    long sum = 0;
    for(int i=0;i<threadNum;i++){
    sum+=calcServ[i].getResult();
    }


    System.out.println("sum="+sum);


    }

    private int[] createArray(int length){
    int[] a = new int[length];

    for(int i=0;i<length;i++){
    a[i] = i+1;
    }

    return a;
    }}
    class CalcArray extends Thread{

    private long result = 0;

    private int[] a = null;
    private int[] b = null;

    private int index1 ,index2;

    public CalcArray(int[] a , int[] b , int index1 , int index2){
    this.a = a;
    this.b = b;
    this.index1 = index1;
    this.index2 = index2;
    }

    public void run(){
    for(int i=index1;i<index2;i++){
    result+=a[i]*b[i];
    }
    }

    public long getResult(){
    return this.result;
    }
    }
      

  2.   

    这样计算的东西他是一个高cpu占用的东西。线程数觉得应该和 cpu的内核数一样,否则不会有什么速度上的提高。最好别用java ,还是 c 写比较好。
      

  3.   

    呵呵 那还不如matlab哪 直接乘 
    找找有没有直接调matlab的api 
    我记得c++有不过要是研究算法当我没说
      

  4.   

    我给你写了一个,你可直接用. 写的比较乱,有些地方可以合并,比较两个wait. 为了说明问题,我给分开写了.import java.util.Vector;public class T2 {
    int backNum=0;
    //定义线程类
    class AddThread extends Thread{
    T2 t2;
    int a = 0;
    int b = 0;
    int result = 0;

    AddThread(T2 t2,int a,int b){
    this.t2 = t2;
    this.a = a;
    this.b = b;
    }

    public void run() {
    result = a*b;
    System.out.println("a="+a+"\tb="+b+"\tresult="+result);
    t2.callBack(result);
    }

    }


    int maxThreadNum = 4; //定义要开启的线程数
    int threadDegree = 0;  //当前是有几个线程在运行

    int sumResult = 0; //最终的相加结果
    // 回调方法
        public synchronized void callBack(int result){
        
         sumResult = sumResult + result;     
         threadDegree--;
         release(); //唤醍主线程
        }
        
       
        //释放等待线程
     public synchronized void release() {
        notifyAll(); 
     }
     
     //判断多线程是否执行完,如果没有就等待,如果执行完就返回
    public synchronized int waitResult(){
    int len = v1.size();
    int i = 0;
    while(true){
    if(len<i+1 && threadDegree==0){ //判断是否全部都执行完了 
    return sumResult;
    }else if(len>=i+1 ){
    new T2.AddThread(this,Integer.parseInt(v1.get(i).toString()),Integer.parseInt(v2.get(i).toString())).start();
    i++; //计数器,记录当前计算到第几个元素了
    threadDegree++;

    }
    System.out.println("len:"+len+"\ti:"+i+"\tthreadDegree:"+threadDegree);

    //如果达到最大线程数,则等待.直到有线程执行完,唤醍它再继续执行
    if(threadDegree>=maxThreadNum ){
    try {
    System.out.println("线程达到最大数,等待...");
    wait(); //让线程等待,直到有人呼醍它(这里采用回调唤醍的办法),不会一直占用CPU
    } catch (InterruptedException e) {
    System.out.println("在等待多线程查询返回结果时出错"+e.getMessage());
    }
    }else if(len==i && threadDegree>0){
    try {
    System.out.println("等待最后的线程返回...");
    wait(); //让线程等待,直到有人呼醍它(这里采用回调唤醍的办法),不会一直占用CPU
    } catch (InterruptedException e) {
    System.out.println("在等待多线程查询返回结果时出错"+e.getMessage());
    }
    }


     }
     }
    Vector v1 = null;
    Vector v2 = null;

    /**
     * @param v1 : 集合1
     * @param v2 : 集合2
     * @param maxThreadNum : 最大线程数
     */
    public T2(Vector v1 ,Vector v2,int maxThreadNum){
    this.v1 = v1;
    this.v2 = v2;
    this.maxThreadNum = maxThreadNum;
    }
    public static void main(String args[])throws Exception{
    long beginTime = System.currentTimeMillis(); //开始时间

    //线两个集合赋测试值(随便给)
    Vector v1 = new Vector();
    Vector v2 = new Vector();
    for(int i=0;i<1000;i++){
    v1.add(""+i+"");
    v2.add(""+(i+1)+"");
    }

    T2 t2 = new T2(v1,v2,4);
    int sumResult = t2.waitResult();

    System.out.println("最终的结果是:"+sumResult);

    long endTime = System.currentTimeMillis();
    System.out.println("共用时"+(endTime-beginTime)+"ms");

    }
    }
      

  5.   

    忘记说了 线程数和元素的个数都是2的N次幂 当然元素数目肯定要是线程数的倍数 其中元素算按两种方法 一种是把元素循环分配给线程 也就是第一个元素分配给第一个线程... 第n个元素分配给第n个线程 最后把每个线程的结果再相加 得到最后的结果  
    另外一种是按块分配 也就是每个线程得到 相同大小的元素块 
    在程序里 通过设置一个变量 来决定按哪种方式运行 变量等于0 就按第一种方法 等于1 则按第二种方法
    而且主程序要能通过command line来获取初始的参数 比如当输入java -server 主类名 65536 16 123456 0, 意味着代码应该创造两个65536大小的向量 并用随机数randon(seed)来产生这些数目, 16代表线程数目 
    能不能再改善一下 万分感谢
      

  6.   

    >>其中元素算按两种方法 一种是把元素循环分配给线程 也就是第一个元素分配给第一个线程... 第n个元素分配给第n个线程 最后把每个线程的结果再相加 得到最后的结果以上有意义吗?!
      

  7.   

    开始的想法如“jackspears007() ”所想,将算式分成N块分配给N个线程处理。不过,同一时间占有CPU资源的永远只有一个线程,那么这样做有什么意义呢?!
    跟这样有什么区别:写一个相加的同步算法,每个获得CPU资源的线程读取继续上一个线程的计算工作。就像4*400米接力赛一样。我想题目中,用4个线程和128个线程来处理这样的计算,就暗示了出题者的目的吧!观察更多线程的计算能力表现。
    可以将两者处理时间做一下比较比较,从start第一个线程开始计时,到算出结果后结束。