zoukankan      html  css  js  c++  java
  • 多线程面试题系列1_数组多线程分解

    多线程优势:
    在i7-8550U CPU平台比单线程快2-4倍以上

    题目:
    (假设多线程数为N)给定N个数组,每个数组中存着DATASIZE = 15000000个数字,为每个数组中的每个数字单独判断一次是否为素数。
    多线程与单线程元素均采用单独素数判断时效率极高的相邻剪枝法(在我另一篇文章中有写),比较之间的差距。
    这里假设N为16,为每个数组填充值为1到15000000的元素。

    需要注意的点:
    在最后归并时需要对同一个对象加锁synchronized,以防static变量更新错误。

    package com.company;
    class Sun implements Runnable {
        private static int THREADLINES;
        private static int DATASIZE;
        public static int answer;
        private int[][] data;
        private Thread[] thread;
    
        Sun(final int DATASIZE, final int THREADLINES) {
            this.DATASIZE = DATASIZE; this.THREADLINES = THREADLINES;
            data = new int[THREADLINES][]; thread = new Thread[THREADLINES];
            for(int i = 0; i < THREADLINES; i++) {
                data[i] = new int[DATASIZE];
                for(int j = 0; j < DATASIZE; j++) {
                    data[i][j] = j + 1;
                }
            }
            for(int i = 0; i < THREADLINES; i++) thread[i] = new Thread(this);
        }
        void stage() {
            for(Thread e : thread) e.start();
        }
        boolean isPrimeNumber(int n)
        {
            if(n == 2 || n == 3)
                return true;
            if(n % 6 != 1 && n % 6 != 5)
                return false;
            for(int i = 5; i <= Math.sqrt(n); i+=6)
            {
                if(n % i == 0 || n % (i+2) == 0)
                    return false;
            }
            return true;
        }
        void getPrimeNumber(int index) {
            int cache = 0;
            for(int i = 0; i < DATASIZE; i++) {
                if(isPrimeNumber(data[index][i]))
                    cache ++;
            }
            synchronized(this) {
                answer += cache;
            }
        }
        public void run() {
            if(Thread.currentThread() == thread[0]) {
                getPrimeNumber(0);
            } else if(Thread.currentThread() == thread[1]) {
                getPrimeNumber(1);
            } else if(Thread.currentThread() == thread[2]) {
                getPrimeNumber(2);
            } else if(Thread.currentThread() == thread[3]) {
                getPrimeNumber(3);
            } else if(Thread.currentThread() == thread[4]) {
                getPrimeNumber(4);
            } else if(Thread.currentThread() == thread[5]) {
                getPrimeNumber(5);
            } else if(Thread.currentThread() == thread[6]) {
                getPrimeNumber(6);
            } else if(Thread.currentThread() == thread[7]) {
                getPrimeNumber(7);
            } else if(Thread.currentThread() == thread[8]) {
                getPrimeNumber(8);
            } else if(Thread.currentThread() == thread[9]) {
                getPrimeNumber(9);
            } else if(Thread.currentThread() == thread[10]) {
                getPrimeNumber(10);
            } else if(Thread.currentThread() == thread[11]) {
                getPrimeNumber(11);
            } else if(Thread.currentThread() == thread[12]) {
                getPrimeNumber(12);
            } else if(Thread.currentThread() == thread[13]) {
                getPrimeNumber(13);
            } else if(Thread.currentThread() == thread[14]) {
                getPrimeNumber(14);
            } else if(Thread.currentThread() == thread[15]) {
                getPrimeNumber(15);
            }
        }
    }
    public class Method {
        private static final int DATASIZE = 15000000;
        private static final int THREADLINES = 16;
        static boolean isPrimeNumber(int n)
        {
            if(n == 2 || n == 3)
                return true;
            if(n % 6 != 1 && n % 6 != 5)
                return false;
            for(int i = 5; i <= Math.sqrt(n); i+=6)
            {
                if(n % i == 0 || n % (i+2) == 0)
                    return false;
            }
            return true;
        }
        public static void main(String[] args) {
            int[][] data = new int[THREADLINES][DATASIZE];
            for(int i = 0; i < THREADLINES; i++) {
                for(int j = 0; j < DATASIZE; j++) {
                    data[i][j] = j + 1;
                }
            }
    
            // 传统方法
            long start = System.currentTimeMillis();
            int sum = 0;
            for(int i  = 0; i < THREADLINES; i++) {
                for(int j = 0; j < DATASIZE; j++)
                    if(isPrimeNumber(data[i][j])) sum ++;
            }
            System.out.println("单线程:	" + sum + "	耗时 " + (System.currentTimeMillis() - start) / 1000.0
    
                    + "秒");
    
            // 多线程
            start = System.currentTimeMillis();
            Sun sun = new Sun(DATASIZE, THREADLINES);
            sun.stage();
            while(true) {
                if(Thread.activeCount() == 2) {
                    System.out.println("多线程:	" + sun.answer + "	耗时 " + (System.currentTimeMillis() - start) / 1000.0
                            + "秒");
                    break;
                }
            }
        }
    }
    

    运行结果:

  • 相关阅读:
    sell -- js, 字符串去重,找到字符串中出现最多次数的字符,且输出多少次
    网络连接不了!
    sell -- js过滤敏感词
    动态绑定HTML
    web前端学习之HTML CSS/javascript之一
    web前端性能优化
    浅谈大型web系统架构
    应用越来越广泛的css伪类
    css3火焰文字样式代码
    7种html5css3网页图片展示特效代码
  • 原文地址:https://www.cnblogs.com/fromneptune/p/11755721.html
Copyright © 2011-2022 走看看