上一篇python并发中讲到了,使用多进程,多线程,多任务来加快程序的运行。其中讲到的一点彷佛有点问题,操做系统中线程是调度器的最小执行单位,那为什么python中的多线程没法利用多核,只能在一个处理器上运行呢?由于python中有GIL(全局解释器锁)这么个东西,固然它只是cpython解释器的一个特性,其余解释器可能没有。java
大学时总在想,学操做系统、计算机组成原理、数据结构有啥用啊?还不如学习如何使用hibernate
、struts
、spring
。当你工做3年后,对如何使用这些工具再也提不起兴趣时或者想深刻了解它到底为何是那样时,你就会从新回过头来打量大学时学的这些底层知识。python
也许你对下面一句话耳熟能详:spring
进程是资源分配的最小单位,线程是最小执行单位。数据结构
大学时读的彻底是字面意思啊?并无思考什么是进程,为什么要搞出来个进程?好吧,下面又是我杜撰的。多线程
进程是一个操做系统级别的概念,运行一个程序时每每须要各类资源,操做系统把一个程序以及运行时所须要的资源抽象成一个进程,这里的资源是存储资源和计算资源。各个进程的计算资源是由操做系统的调度器统一分配的,而不是一个进程永远霸占计算资源;由于进程使用的是虚拟内存地址,不一样进程的同一虚拟地址可能映射到了不一样的物理内存上,因此不一样进程间的存储资源是不共享的。并发
由于进程的储存资源不共享,建立销毁和切换的开销比较大。因此出现了轻量级进程,即线程。线程是共享同一进程的存储资源的,一个进程能够建立若干线程。同时它也是调度器的最小执行单元,可见多线程是能利用多核处理器的。工具
java没有操做进程并发的类,官方暂时也不支持协程,可是有一些第三方库,比Quasar。下面是多线程的几种方式:学习
ThreadPoolExecutor
CompletableFuture
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.concurrent.*; import java.util.stream.IntStream; public class ThreadPoolDemo { static String content = "1234567890abcdefghijklmnopqrstuvwxyz"; static int size = 400; public static void a(){ int cnt = Runtime.getRuntime().availableProcessors() * 2 + 1; ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(cnt); ArrayList<Future<?>> fs = new ArrayList<>(size); long start = System.currentTimeMillis(); for(int i = 0; i < size; ++i){ int seq = i; Future<?> f = threadPoolExecutor.submit(() -> createFile("a", seq)); fs.add(f); } for(Future<?> f : fs){ try { f.get(); } catch (InterruptedException|ExecutionException e) { e.printStackTrace(); } } System.out.println(String.format("%s = %s", "a", (System.currentTimeMillis() - start))); threadPoolExecutor.shutdown(); } public static void b(){ CountDownLatch countDownLatch = new CountDownLatch(size); long start = System.currentTimeMillis(); for(int i = 0;i<size;++i){ int seq = i; CompletableFuture .runAsync(()->createFile("b", seq)) .whenComplete((r, e)->{ countDownLatch.countDown(); }); } try { countDownLatch.await(); System.out.println(String.format("%s = %s", "b", (System.currentTimeMillis() - start))); } catch (InterruptedException e) { e.printStackTrace(); } } public static void c(){ long start = System.currentTimeMillis(); IntStream.range(0, size) .parallel() .forEach(e -> { createFile("c", e); }); System.out.println(String.format("%s = %s", "c", (System.currentTimeMillis() - start))); } public static void createFile(String prefix, int name){ File file = new File("D:/files/" + prefix + "_" + name); if(!file.exists()){ try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } try (FileOutputStream fos = new FileOutputStream(file)) { fos.write(content.getBytes()); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { // a(); //b(); c(); } }