为什么需要并行?– 业务要求– 性能并行计算还出于业务模型的需要– 并不是为了提高系统性能,而是确实在业务上需要多个执行单元。– 比如HTTP服务器,为每一个Socket连接新建一个处理线程– 让不同线程承担不同的业务工作– 简化任务调度Linus Torvalds :并行计算只有在 *图像处理* 和 *服务端编程* 2个领域可以使用,并且它在这2个领域确实有着大量广泛的使用。但是在其它任何地方,并行计算毫无建树!计算密集型在多核时代,一般没有必要特别区分并发和并行 同步(synchronous)和异步(asynchronous) 并发(Concurrency)和并行(Parallelism) 临界区 阻塞(Blocking)和非阻塞(Non-Blocking)– 阻塞和非阻塞通常用来形容多线程间的相互影响。比如一个线程占用了临界区资源,那么其它所有需要这个资源的线程就必须在这个临界区中进行等待,等待会导致线程挂起。这种情况就是阻塞。此时,如果占用资源的线程一直不愿意释放资源,那么其它所有阻塞在这个临界区上的线程都不能工作。– 非阻塞允许多个线程同时进入临界区 锁(Deadlock)、饥饿(Starvation)和活锁(Livelock) 并行的级别并发级别– 阻塞– 非阻塞– 无障碍 – 无锁– 无等待有关并行的2个重要定律 Amdahl定律(阿姆达尔定律) Gustafson定律(古斯塔夫森)进程切换是一个重量级的操作,需要消耗大量的计算资源在Java中的线程会直接映射到操作系统的线程上去Thread t1 = new Thread();
t1.start(); // 开启线程进入就绪状态Thread t2 = new Thread();
t2.run();   // 不能开启线程,在本线程内执行run方法  继承Thread重写run方法,MyThread extends Thread
new Thread(new Runnable() {}).start();Thread.stop()不建议使用@Deprecated,太过暴力,类似于Linux强制杀死进程:kill -9 thread_idpublic static native void sleep(long millis) throws InterruptedException
public void run() {while (true) {if (Thread.currentThread().isInterrupted()) {System.out.println("Interruted!");break;}try {Thread.sleep(2000);} catch (InterruptedException e) {System.out.println("Interruted When Sleep");// 设置中断状态,抛出异常后会清除中断标记位 ********Thread.currentThread().interrupt();}Thread.yield();}
}suspend()、resume()等待线程结束(join)和谦让(yeild)join的本质:while(isAlive()) {wait(0);}线程执行完毕后,系统会调用notifyAll();   ===> 可以不需要在线程实例上使用wait()和notifyAll()守护线程 在后台默默地完成一些系统性的服务,比如垃圾回收线程、 JIT线程就可以理解为守护线程 当一个Java应用内,只有守护线程时,Java虚拟机就会自然退出Thread t = new DaemonT();t.setDaemon(true);t.start();高优先级的线程更容易再竞争中获胜基本的线程同步操作 synchronized– 指定加锁对象:对给定对象加锁,进入同步代码前要获得给定对象的锁。public void run() {for(int j = 0; j < 10000000; j++) {synchronized(instance) {i++;}}}– 直接作用于实例方法:相当于对当前实例加锁,进入同步代码前要获得当前实例的锁。public synchronized void increase(){i++;}– 直接作用于静态方法:相当于对当前类加锁,进入同步代码前要获得当前类的锁。public static synchronized void increase(){i++} Object.wait() Obejct.notify()public static class T1 extends Thread {public void run() {synchronized (object) {System.out.println(System.currentTimeMillis()+":T1 start!");try {System.out.println(System.currentTimeMillis() + ":T1 wait for object ");object.wait();} catch (InterruptedException e) {e.printStackTrace();}System.out.println(System.currentTimeMillis()+":T1 end!");}}}public static class T2 extends Thread {public void run() {synchronized (object) {System.out.println(System.currentTimeMillis() +":T2 start! notify one thread");object.notify();System.out.println(System.currentTimeMillis()+":T2 end!");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}}}1425224592258:T1 start!1425224592258:T1 wait for object1425224592258:T2 start! notify one thread1425224592258:T2 end!1425224594258:T1 endnotify() VS notifyAll()notify()随机唤醒一个线程,notifyAll()唤醒全部等待此监视器的线程,让他们去竞争这个监视器的使用权》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》Java内存模型和线程安全  原子性           原子性是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其它线程干扰。 有序性在并发时,程序的执行可能就会出现乱序。一条指令的执行是可以分为很多步骤的(*数据旁路技术*&*指令重排*可以使流水线更加流畅,指令重排不能出现语义问题)– 取指 IF– 译码和取寄存器操作数 ID– 执行或者有效地址计算 EX– 存储器访问 MEM– 写回 WB 可见性可见性是指当一个线程修改了某一个共享变量的值,其他线程是否能够立即知道这个修改。– 编译器优化– 硬件优化(如写吸收,批操作)Java虚拟机层面的可见性(volatile) Happen-Before 程序顺序原则:一个线程内保证语义的串行性 volatile规则:volatile变量的写,先发生于读,这保证了volatile变量的可见性 锁规则:解锁(unlock)必然发生在随后的加锁(lock)前 传递性:A先于B,B先于C,那么A必然先于C 线程的start()方法先于它的每一个动作 线程的所有操作先于线程的终结(Thread.join()) 线程的中断(interrupt())先于被中断线程的代码 对象的构造函数执行结束先于finalize()方法 线程安全的概念指某个函数、函数库在多线程环境中被调用时,能够正确地处理各个线程的局部变量,使程序功能正确完成。ReentrantLock(重入锁 )是synchronized关键字的增强,目前两者性能不相上下。ReentrantLock可重入可多次加锁可中断发生死锁时,可启用一个守护线程去中断某一线程从而达到解锁目的可限时避免死锁和长期等待锁公平锁 公平锁虽然不会产生饥饿但是由于公平锁需要解决排队问题(先到先得),所以性能较非公平锁差,没有特殊要求没必要使用公平锁。JDK并发包--并发容器及典型源码分析 集合包装 HashMap --> 适用小并发量,串行解决方案,非高并发解决方案public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {return new SynchronizedMap<>(m);} Listpublic static <T> List<T> synchronizedList(List<T> list) {return (list instanceof RandomAccess ?new SynchronizedRandomAccessList<>(list) :new SynchronizedList<>(list));} Setpublic static <T> Set<T> synchronizedSet(Set<T> s) {return new SynchronizedSet<>(s);} ConcurrentHashMapConcurrentHashMap(HashMap底层使用数组实现,因此为实现大规模高并发,可将整个数组分成N个段<Segment>,一个就可供N个线程同时写入数据,理论提高效率N倍)put()方法各个Segment有各自的锁,get()方法无锁,但是在size()方法中需要拿到所有Segment的锁后才能统计数据,但size()方法并非一个高频率调用的函数。之所是高性能,是因为不会随随便便就加锁,而是经过自旋等待在有必要的时候才加锁。 BlockingQueue阻塞队列,是一个接口,线程安全,不是一个高性能的容器,但是BlockingQueue是一个非常好的**在多个线程中共享数据的容器**若为空队列,此时有线程尝试读取数据,则此读的线程会等待,直到有另外线程往队列中写入数据,则读的线程就会被唤醒并且读取数据;若队列已经写满了,则写入的线程就会等待,直到有线程读取数据有空闲空间后才能写入队列;因此Blocking会引起线程阻塞。BlockingQueue作为生产者消费者容器很方便。put()、take()实现:ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue。 ConcurrentLinkedQueue类似ConcurrentHashMap的高性能Queue,内部使用了大量的无锁操作。offer()、poll() BlockingQueue VS ConcurrentLinkedQueue在并发编程中我们有时候需要使用线程安全的队列。如果我们要实现一个线程安全的队列有两种实现方式:一种是使用**阻塞算法**,另一种是使用**非阻塞算法**。使用阻塞算法的队列可以用一个锁(入队和出队用同一把锁)或两个锁(入队和出队用不同的锁)等方式来实现,而非阻塞的实现方式则可以使用循环CAS的方式来实现。

》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

对于我们的业务来说:线程的创建和销毁与业务无关,只关心是否执行了任务,毕竟创建销毁需要消耗计算资源,因此我们希望将更多的资源用于执行任务而不是用在辅助性质的线程创建和销毁上。

线程池限流

内置线程池的种类(Executors对应的方法)
  newFiexedThreadPool 固定大小的线程池
  newSingleThreadExecutor 只有一个线程的线程池
  newCachedTHreadPool 弹性线程池
  newScheduledTHreadPool 定时任务,执行某个线程

newFiexedThreadPool()、newSingleThreadExecutor()、newCachedTHreadPool()三个方法底层都是通过类ThreadPoolExecutor实现的,其典型构造方法(4个)为
  public ThreadPoolExecutor(int corePoolSize, // 核心线程数
                 int maximumPoolSize, // 最大线程数
                 long keepAliveTime, // 超过核心线程数的空闲线程最大存活时间
                 TimeUnit unit, // 时间单位
                 BlockingQueue<Runnable> workQueue) // 当线程池满载运行时存放新任务的阻塞队列,newCachedTHreadPool()例外,使用了SynchronousQueue

内置线程池使用:
  MyThread task = new MyThread();
  ExecutorService es = Executors.newFixedThreadPool(5);
  for (int idx = 0; idx < 10; ++idx) {
    es.submit(task);
  }

ExecutorService类
  shutdown()
  isShutdown() : boolean
  isTerminated() : boolean
  submit(Callable task) : Future

Java并发笔记-未完待续待详解相关推荐

  1. Java并发编程之CountDownLatch/CyclicBarrierDemo/SemaphoreDemo详解

    CountDownLatch详解 什么是CountDownLatch? 代码说明一 :班长锁门 代码说明二:秦国统一六国 什么是CyclicBarrierDemo? 代码说明一:集齐7个龙珠,召唤神龙 ...

  2. Java并发编程之LinkedTransferQueue阻塞队列详解

    简介 LinkedTransferQueue是一个由链表结构组成的无界阻塞TransferQueue队列.相对于其他阻塞队列,LinkedTransferQueue多了tryTransfer和tran ...

  3. linux安装java学习环境(未完待续)

    linux安装java学习环境 数据库连接命令 连接mysql数据库 格式为: mysql -hip地址 -p端口号 -u root -p 输入密码例如: mysql -hlocalhost -p33 ...

  4. JNI方面的笔记(未完待续)

    Microsoft Windows [版本 6.1.7600] 版权所有 (c) 2009 Microsoft Corporation.保留所有权利. C:\Users\toto>javah 用 ...

  5. 剑指Offer:面试题33——把数组排成最小的数(java实现)(未完待续)

    问题描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 思路1: ...

  6. TS学习笔记 ---未完待续....

    TS学习笔记 1 .ts文件与.tsx文件有什么区别 2.使用TS之前需要配置 3.TS特性 泛型和类型注解有什么区别? 3.什么是泛型参数? 4.函数.类.接口有什么区别? 4.1 一个class不 ...

  7. 面渣逆袭:Java并发六十问,图文详解,快来看看你会多少道

    基础 1.并行跟并发有什么区别? 从操作系统的角度来看,线程是CPU分配的最小单位. 并行就是同一时刻,两个线程都在执行.这就要求有两个CPU去分别执行两个线程. 并发就是同一时刻,只有一个执行,但是 ...

  8. Java并发六十问,图文详解

    干货 基础 1.并行跟并发有什么区别? 从操作系统的角度来看,线程是CPU分配的最小单位. 并行就是同一时刻,两个线程都在执行.这就要求有两个CPU去分别执行两个线程. 并发就是同一时刻,只有一个执行 ...

  9. Java学习笔记 | 尚硅谷项目三详解

    该笔记基于B站视频:尚硅谷Java入门视频教程 目录 1,目标 2,需求说明 2.1,功能实现 2.1,菜单显示 2.2,添加功能 2.3,删除功能 2.3,查看团队成员 3,软件设计结构 4,具体实 ...

最新文章

  1. 智慧电梯物联网 未来电梯将更智能
  2. 香港金管局批出首批五张支付工具牌照,支付宝、微信支付等“合法”上岗
  3. 开发日记-20190910 Makefile相关(一)
  4. ArcGIS怎样获取重分类后各类所占的像元个数
  5. HTML如何添加锚点,干货满满
  6. 嵌入式linux的tftp配置[ZT]
  7. 智能一代云平台(二十四):已安装的Nginx上安装echo插件
  8. php分享十七:http状态码
  9. 【对讲机的那点事】对讲机数字语音加密,保障通信安全
  10. 经典字符串匹配算法——KMP算法
  11. 半小时漫画股票实战法观看记录,观看更新
  12. [Android Pro] proguard.cfg 配置文件
  13. 卡尔曼滤波简介(转载)
  14. apmserv中 php版本,APMServ5.2.6的PHP版本升级到5.3、5.4版本的方法
  15. 关于STM32 Hal 库函数编写的程序 在编译时报错 :“Error: L6218E: Undefined symbol 函数名 (referred from xx.o)” 的解决办法
  16. 大学计算机专业相关证书有哪些,大学必考8大证书 哪些最实用
  17. 自己整理的小学教师资格证结构化面试题分享
  18. 使用Access时遇到的问题
  19. HTML5 + CSS3
  20. 联想笔记本e480恢复出厂设置_联想ThinkPad E480笔记本win10怎么改win7

热门文章

  1. Spring2.5学习笔记1-控制反转-Autowiring策略(续)
  2. NUCLEUS:13:西门子实时操作系统 Nucleus漏洞影响物联网设备等
  3. 热门开源 WYSIWYG 编辑器 TinyMCE 被指存在严重的 XSS 漏洞
  4. jQuery基础系列
  5. ubuntu server 10.4下LAMP的安装
  6. shell入门(一)
  7. 前端学数据库之子查询
  8. Android入门学习4
  9. 数据绑定--Repeater, DataList, or GridView?
  10. [ZT]ASP.NET中如何防范SQL注入式攻击