并发编程的目的是为了使程序运行更快,但是,并不意味着启动更多线程就可让程序最大限度并发执行
CPU为不同线程分配不同的时间块来支持多线程执行代码(类似于时分复用),但是在切换到下一个任务之前,会将现在这个任务状态保存,以便下次可以再加载这个任务状态。任务从保存到再加载的过程就称为依次上下文切换
package com.chapter1; import static java.lang.System.currentTimeMillis; public class ConcurrentTest { private static long count = 100000000; public static void main(String[] args) throws InterruptedException { concurrency(); serial(); } //并发计算结果 private static void concurrency() throws InterruptedException { long start = currentTimeMillis(); //开启一个线程计算结果 Thread thread = new Thread(()->{ long sum = 0; for (int i = 0; i < count; i++) { sum = sum + 5; } }); thread.start(); //主线程循环减 int b = 0; for (int i = 0; i < count; i++) { b--; } //插队 thread.join(); long time = System.currentTimeMillis() - start; System.out.println("concurrency:" + time); } //普通单线程计算 private static void serial() { long start = System.currentTimeMillis(); long sum = 0; for (int i = 0; i < count; i++) { sum = sum + 5; } int b = 0; for (int i = 0; i < count; i++) { b--; } long time = System.currentTimeMillis() - start; System.out.println("serial:" + time); } }
通过例子发现,随着count的值增加,多线程优势逐渐显现出来,在count较小时,所用时间大于单线程时间。经过分析发现,这是因为上下文切换带来的时间损耗。
减少上下文切换方法有:无锁并发编程,CAS算法,使用最少线程和使用协程
死锁产生的四个必要条件:
package com.chapter1; import java.util.concurrent.TimeUnit; public class DeadLockTest { //两个资源 private static String A = "A"; private static String B = "B"; public static void main(String[] args) { deadlock(); } private static void deadlock() { //开启t1线程 new Thread(()->{ synchronized (A) { System.out.println(Thread.currentThread().getName() + "get A"); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (B) { System.out.println(Thread.currentThread().getName() + "get B"); } } }, "t1").start(); //开启t2线程 new Thread(()->{ synchronized (B) { System.out.println(Thread.currentThread().getName() + "get B"); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (A) { System.out.println(Thread.currentThread().getName() + "get A"); } } }, "t2").start(); } }
避免死锁的几个常用方法:
什么是资源限制
资源限制是指在并发编程中,程序执行速度受限于计算机硬件资源或软件资源
资源限制引发的问题
并发编程的原则是将代码中串行执行的部分编程并发执行。但由于资源限制问题,本质上还是串行,同时由于上下文切换和资源调度问题,时间反而会增加。
如何解决资源限制问题
硬件资源限制:使用集群并行执行程序。让程序在多个计算机上执行,比如使用ODPS,Hadoop搭建服务器集群
软件资源限制:使用资源池将资源复用。
资源限制下的并发编程
在资源限制下,根据不同的资源限制调整程序的并发度。