刚开始接触java的时候对多线程老是怀抱着好奇心,总想弄明白多线程的好处,为何要使用多线程编程。甚至于认为使用多线程就比单线程要高大上、要好。但事实真的是这样吗?下面就举一个案列看看java
/** * 线程池类 */ public class CustomThreadPoolExecutor { private ThreadPoolExecutor pool = null; /** * 线程池初始化 */ public void initialize() { //ThreadPoolExecutor的构造函数接收4个参数: //corePoolSize 核心线程池大小 //maximumPoolSize 最大线程池大小 //keepAliveTime 最大存活时间 //unit eepAliveTime时间单位 //workQueue 阻塞队列 pool = new ThreadPoolExecutor(20, 50, 30, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(10)); } /** * 销毁线程池 */ public void destroy() { if(pool!=null) { pool.shutdown(); } } /** * 获取线程池对象 * @return */ public ExecutorService getCustomThreadPoolExecutor() { return this.pool; } }
/** * 图书类 */ public class Book implements Comparable<Book>{ private String id; // id private String name; //书名 private Long sales; //销量 //省略getter,setter 方法 @Override public int compareTo(Book o) { Long diff = this.getSales() - o.getSales(); if (diff > 0) { return 1; }else if(diff<0) { return -1; } return 0; }
public class ProvideBooks { /** * 获取图书集合 * @return */ public static List<Book> getBookList(){ List<Book> bookList = new ArrayList<>(); int l=4000; for (int i = 0; i < l; i++) { Random random = new Random(); Book book=new Book(); int sales= random.nextInt(100); book.setSales(Long.valueOf(sales)); book.setId(UUID.randomUUID().toString().replace("-","")); book.setName("大江大河"); bookList.add(book); } return bookList; } }
public class Main1 { public static void main(String[] args) { Long start=System.currentTimeMillis(); QueryDao queryDao=new QueryDao(); //获取 bookList List<Book> bookList = ProvideBooks.getBookList(); // 每1000条数据开启一条线程 int threadSize = 1000; // 总数据条数 int dataSize = bookList.size(); //System.out.println("书籍类别数:"+dataSize); // 线程数 int threadNum = dataSize / threadSize + 1; System.out.println("线程数量:" + threadNum); // 定义标记,过滤threadNum为整数 boolean special = dataSize % threadSize == 0; // 建立一个线程池 CustomThreadPoolExecutor executor = new CustomThreadPoolExecutor(); executor.initialize(); ExecutorService pool = executor.getCustomThreadPoolExecutor(); // 肯定每条线程的数据 List<Book> cutList = null; // 分割bookList for (int i = 0; i < threadNum; i++) { if (i == threadNum - 1) { if (special) { break; } cutList = bookList.subList(threadSize * i, dataSize); } else { cutList = bookList.subList(threadSize * i, threadSize * (i + 1)); } final List<Book> compareList = cutList; //(放到线程池中,线程异步执行) pool.execute(new Runnable() { @Override public void run() { //Collections.sort(compareList); for (Book book : compareList) { String sql = "insert into book(id,name,sales) values(?,?,?)"; int result = 0; synchronized (queryDao){ if (queryDao.getConnection()) { result = queryDao.executeUpdate(sql, book.getId(), book.getName(), book.getSales()); } } if(result>0){ //System.out.println("插入成功"); } } } }); } executor.destroy();//销毁 while(true){ if(pool.isTerminated()){ System.out.println("全部的子线程都结束了!"); break; } } Long end=System.currentTimeMillis(); System.out.println("总共花费了--"+(end - start)/1000+"."+(end - start) % 1000 +"--s"); } }
结果以下:
web
public class Main2 { public static void main(String[] args) { Long start = System.currentTimeMillis(); QueryDao queryDao=new QueryDao(); //获取 bookList List<Book> bookList = ProvideBooks.getBookList(); // 总数据条数 int dataSize = bookList.size(); //System.out.println("书籍类别数:"+dataSize); int result=0; for(Book book:bookList){ String sql="insert into book(id,name,sales) values(?,?,?)"; if(queryDao.getConnection()){ result=queryDao.executeUpdate(sql, book.getId(), book.getName(), book.getSales()); } if(result>0){ //System.out.println("插入成功"); } } Long end = System.currentTimeMillis(); System.out.println("总共花费了--" + (end - start) / 1000+"."+(end - start) % 1000 + "--s"); } }
结果以下:sql
从上述结果中能够看出,多线程下居然还比单线程慢了0.3秒左右。可见多线程下的效率并不必定比单线程的高。固然跟个人测试数据量也有必定的关系。有兴趣的能够看看《并发编程的艺术》这本书。我这里就再也不阐述缘由了。编程