8皇后以及N皇后算法探究,初试多线程

原创链接:http://www.hexcode.cn/article/4088/show

 

接连写了几篇关于8皇后问题的算法研究的博客

最终还是觉得回溯算法比较直观,但是效率偏低

于是想研究一下JAVA的多线程编程,下面是初次使用多线程编程的计算性能实测

首先给一个没有使用多线程编程的例子:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static void main(String[] args) {
    Date begin = new Date();
 
    long sum = 0;
    int taskSize = 100;
     
    for (int i = 0; i < taskSize; i++) {
        sum += math(i * 1999999999);
    }
     
 
    Date end = new Date();
    System.out.println("用时:" + String.valueOf(end.getTime() - begin.getTime()) + "毫秒,计算结果:" + sum);
}
 
private static long math(int n) {
    long sum=0;
    for(int i=0;i<n;i++){
        sum+=i;
    }
    return sum;
}

执行效率为24秒,截图如下:

Image 2.png

 

下面使用JAVA的ExecutorService,编写带有返回值的多线程代码

带有返回值的多线程接口Callable是JAVA1.5之后引入的,完美的解决了多线程编程带有返回值的问题

在这之前在JAVA中要使用synchronized 关键字做同步锁,显得相当繁琐,而且极易出错,导致程序死锁

现在有了线程池和Callable接口,一切显得相当方便,实现上述计算的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package com.newflypig.eightqueen;
 
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
 
public class EightQueen6 {
    public static void main(String[] args) throws Exception{
        Date begin=new Date();
         
        long sum=0;
        int taskSize = 100;
        // 创建一个线程池
        ExecutorService pool = Executors.newFixedThreadPool(taskSize);
        // 创建多个有返回值的任务
        List<Future<Long>> list = new ArrayList<Future<Long>>();
        for (int i = 0; i < taskSize; i++) {
            Callable<Long> c = new MyCallable(i*1999999999);
            // 执行任务并获取Future对象
            Future<Long> f = pool.submit(c);
            // System.out.println(">>>" + f.get().toString());
            list.add(f);
        }
        // 关闭线程池
        pool.shutdown();
         
        for(Future<Long> f : list){
            sum+=f.get();
        }
         
        Date end = new Date();
        System.out.println("用时:" + String.valueOf(end.getTime() - begin.getTime()) + "毫秒,计算结果:"
                + sum);
    }
}
 
class MyCallable implements Callable<Long>{
    private int n;
    private long sum=0;
     
    public MyCallable(int n){
        this.n=n;
    }
     
    @Override
    public Long call() throws Exception {
        for(int i=0;i<n;i++){
            sum+=i;
        }
        return sum;
    }
     
}

执行效率大大提升到5800毫秒,截图如下:

Image 3.png

上述代码在执行过程中,一下子创建了100个线程同时计算子结果集,最终使用Future泛型类将计算得到的long型子结果累加得到最终结果,运行过程中8核CPU能做到满负荷运转,截图如下:

1451827510259164144.png

 

看到这样的CPU运转图线我确实很兴奋,因为在计算8皇后问题时,无论回溯算法的复杂度多高,无论是否使用递归函数,我的代码运行时,CPU负载一直在15%以下,根本没有充分利用计算机性能。

 

下一步就是利用所学的多线程编程,来计算N皇后的问题,希望性能上有所突破。

posted on 2016-01-03 21:39  丁丁·全栈工程师  阅读(1230)  评论(0编辑  收藏  举报

导航