一、并发编程的发展历史

  并发设计主导者 Doug Lea

  谈谈学习方法

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

    1.场景-->需求-->解决方案-->应用-->原理

      案例:

        1.1 并发 并发的场景是为了提高程序的吞吐性能及实时性
        1.2 dubbo 在分布式环境下,存在服务治理的需求,采用的解决方案就是dubbo,首先知道如何去应用他,进而去了解它的原理

        1.3 JVM 一次编译到处运行,存在这跨平台的需求,而不同的操作系统平台之间存在这巨大的差异,如何解决这种差异,就在操作系统和我们的应用软件之间架设一层虚拟的操作系统,即JVM,而如何去应用,就是安装JDK,通过虚拟机将虚拟机语言编译成支持跨平台字节码,然后去运行。而想要更加灵活地去运用,就要去了解JVM的底层原理,包括他的内存结构,垃圾回收机制,垃圾回收机制算法等。

  随着硬件的演变,软件随之演变

  1.真空管/穿孔打卡

    最早是为了解决数学计算问题。在卡片输入之前计算机大部分处理空闲状态。

    并发专题(一)--初识多线程的发展及应用 随笔 第1张

 

  2.晶体管/批处理操作系统

    好处是工作时,计算机不需要等待,可以解决计算机空闲问题。但同时也存在了新的问题,那就是IO问题,一旦在处理一个指令或者计算时造成阻塞,就会造成CPU的资源浪费。

    那么就会产生一个需求-->如果最大化利用CPU资源?

    并发专题(一)--初识多线程的发展及应用 随笔 第2张

 

  3.集成电路/多道程序设计

    进程的出现,使得内存空间被分成多个互不影响的空间,如果进程A阻塞,并不妨碍进程B的运行。在用户层面看是并发的,但在CPU层面是进行了时间片的切换。而在切换的过程过会记录进程的位置。

    并发专题(一)--初识多线程的发展及应用 随笔 第3张

  4.最后引出我们的猪脚--线程?

    1.单核->多核->真正意义上的达到并行计算。

      在不同的CPU中处理相同的计算机指令。

    2.真正意义上的需求--实时性。

      在一个进程中会出现多个任务。如何保证多个任务是实时性的。轻量级的进程,线程使得CPU切换的成本更低。在多核时代资源利用率更高。

    3.线程可以合理的利用多核心的CPU资源,提高程序的吞吐量

二、线程在java中的应用

  1.如何在java中实现线程?

    1.1 Runnable接口

    1.2 Thread类(本质上是对Runnable接口的实现)

       1.3 Callable/Future 带返回值的线程()

     1.4 TheadPool 

三、多线程的实际应用场景

  1.线程池,new Thread() 会造成我们对资源的不可控。

    财务类:文件跑批,收益文件,对账文件。

    BIO模型优化    

并发专题(一)--初识多线程的发展及应用 随笔 第4张
1 Socket socket = socket.accept();    //连接阻塞
2 
3 socket = socket.inputsteam();        //读取阻塞
4 socket = socket.outputsteam();      //写入阻塞
5 
6 //解决方式
7 new Thread(new Handler(socket)).start(); //解决了r/w阻塞问题。
BIO模型优化

    zookepper责任链模型

并发专题(一)--初识多线程的发展及应用 随笔 第6张
  1 package com.jlDemo.ConcurrentFirstChapter.ThreadDemo;
  2 
  3 /**
  4  * @author jar luo
  5  * @time 2019.4.22
  6  */
  7 public class Request {
  8     private String name;
  9 
 10     public String getName() {
 11         return name;
 12     }
 13 
 14     public void setName(String name) {
 15         this.name = name;
 16     }
 17 
 18     @Override
 19     public String toString() {
 20         return "Request{" +
 21                 "name='" + name + '\'' +
 22                 '}';
 23     }
 24 }
 25 
 26 package com.jlDemo.ConcurrentFirstChapter.ThreadDemo;
 27 /**
 28  * @author jar luo
 29  *
 30  * @time  2019.4.22
 31  */
 32 public interface RequestProcessor {
 33 
 34     void processorRequest(Request request);
 35 
 36 }
 37 
 38 
 39 package com.jlDemo.ConcurrentFirstChapter.ThreadDemo;
 40 
 41 import java.util.concurrent.LinkedBlockingQueue;
 42 
 43 /**
 44  * @author jar luo
 45  * @time 2019.4.22
 46  * @desc 打印请求的内容--借鉴zk的责任链思想
 47  */
 48 public class PrintProcesser extends Thread implements RequestProcessor {
 49 
 50     LinkedBlockingQueue<Request> linkedBlockingQueue = new LinkedBlockingQueue();
 51 
 52     private final RequestProcessor nextProcessor;
 53 
 54     public PrintProcesser(RequestProcessor nextProcessor) {
 55         this.nextProcessor = nextProcessor;
 56     }
 57 
 58     @Override
 59     public void run() {
 60         while (true){
 61             try {
 62                 Request request = linkedBlockingQueue.take();
 63                 System.out.println("print data:" + request);
 64                 nextProcessor.processorRequest(request);
 65             } catch (InterruptedException e) {
 66                 e.printStackTrace();
 67             }
 68         }
 69     }
 70 
 71     @Override
 72     public void processorRequest(Request request) {
 73         linkedBlockingQueue.add(request);
 74     }
 75 }
 76 
 77 
 78 package com.jlDemo.ConcurrentFirstChapter.ThreadDemo;
 79 
 80 import java.util.concurrent.LinkedBlockingQueue;
 81 
 82 /**
 83  *
 84  */
 85 public class SaveProcessor extends Thread implements RequestProcessor{
 86 
 87     LinkedBlockingQueue<Request> linkedBlockingQueue = new LinkedBlockingQueue();
 88 
 89 
 90     @Override
 91     public void run() {
 92         while (true){
 93             try {
 94                 Request request = linkedBlockingQueue.take();
 95                 System.out.println("save data:" + request);
 96             } catch (InterruptedException e) {
 97                 e.printStackTrace();
 98             }
 99         }
100     }
101 
102     @Override
103     public void processorRequest(Request request) {
104         linkedBlockingQueue.add(request);
105     }
106 }
107 
108 
109 package com.jlDemo.ConcurrentFirstChapter.ThreadDemo;
110 
111 /**
112  *
113  */
114 public class Demo {
115 
116     PrintProcesser printProcesser ;
117 
118     public Demo() {
119         SaveProcessor saveProcessor = new SaveProcessor();
120         saveProcessor.start();
121         printProcesser = new PrintProcesser(saveProcessor);
122         printProcesser.start();
123     }
124 
125 
126 
127     public static void main(String[] args) {
128         Request request = new Request();
129         request.setName("jar luo");
130         new Demo().doTest(request);
131     }
132 
133     public void doTest(Request request){
134         printProcesser.processorRequest(request);
135     }
136 
137 
138 }
139 
140 ThreadDemo
ZK责任链模型

     消息中间件

  2.如何去改造自己的程序去实现异步处理呢->异步消息队列去解决

四、线程的生命周期

  1.线程的状态 6种

    1.1 NEW  没有调用start()方法,初始状态

    1.2 RUNNABLE  运行状态

    1.3 BLOCKED  阻塞

      等待阻塞  wait 

      同步阻塞  synchronize

      其他阻塞  sleep/join/

    1.4 WAITING  等待

    1.5 TIMED_WAITING  时间等待

    1.6 TERMINATED  终止

  2.状态关系图图例:

      

      并发专题(一)--初识多线程的发展及应用 随笔 第8张

五、线程的基本操作--启动/终止

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄