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秒,截图如下:
下面使用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毫秒,截图如下:
上述代码在执行过程中,一下子创建了100个线程同时计算子结果集,最终使用Future泛型类将计算得到的long型子结果累加得到最终结果,运行过程中8核CPU能做到满负荷运转,截图如下:
看到这样的CPU运转图线我确实很兴奋,因为在计算8皇后问题时,无论回溯算法的复杂度多高,无论是否使用递归函数,我的代码运行时,CPU负载一直在15%以下,根本没有充分利用计算机性能。
下一步就是利用所学的多线程编程,来计算N皇后的问题,希望性能上有所突破。
保持着对万物的好奇心。即使是玩游戏,也要停下来想想这是怎么实现的。