并发与多线程

  • 目前 CPU 的运算速度已经达到百亿次每秒,甚至更高的量级,家用电脑即使维 持操作系统正常运行的进程也会有数十个,线程更是数以百计。所以,在现实场景中, 为了提高生产率和高效地完成任务,处处均采用多线程和并发的运作方式。
  • 首先从** 并发( Concurrency )与并行( Parallelism ) **说起。并发是指在某个时间段 内,多任务交替处理的能力。所谓不患寡而患不均,每个 CPU 不可能只顾着执行某 个进程,让其他进程一直处于等待状态。所以, CPU把可执行时间均匀地分成若干份, 每个进程执行一段时间后,记录当前的工作状态,释放相关的执行资源并进入等待状 态,让其他进程抢占 CPU 资源。并行是指同时处理多任务的能力。目前, CPU 已经 发展为多核,可以同时执行多个互不依赖的指令及执行块。并发与并行两个概念非常 容易混淆,它们的核心区别在于进程是否同时执行。以 KTV 唱歌为例,并行指的是 有多少人可以使用话筒同时唱歌,并发指的是同一个话筒被多个人轮流使用。
  • 并发与并行的目标都是尽可能快地执行完所有任务。以医生坐诊为例,某个科室 有两个专家同时出诊,这就是两个并行任务,其中一个医生,时而问诊,时而查看 化验单,然后继续问诊,突然又申断去处理病人的咨询,这就是并发。在并发环境下, 由于程序的封闭’|全被打破,出现了以下特点:
  1. 并发挥序之间有侣可制约的关系。 直接制约体现为一个程序需要另一个程 序的计算结果,间接制约体现为多个程序竞争共享资源,如处理器、缓冲区等。
  2. 并发程序的妆,句 1兰特是断断续续的。 程序需要记忆现场指令及执行点。
  3. 当并发数设置合理并且 CPU 拥有足够的处理能力句,并发会提高程序的运行效率。

@toc

1线程安全

线程是 CPU 调度和分派的基本单位,为了更充分地利用 CPU 资源,一般都会使 用多线程进行处理。多线程的作用是提高任务的平均执行速度,但是会导致程序可理 解性变差,编程难度加大。
线程可以拥有自己的操作枝、程序计数器、局部变量表等资源,它与同-进程 内的其他线程共享该进程的所有资源。线程在生命周期内存在多种状态。有 NEW (新建状态)、 RUNNABLE (就绪状态)、 RUNNING (运行状 态)、 BLOCKED (阻塞状态)、 DEAD (终止状态)五种状态。
为保证线程安全,在多个线程并发地竞争共享资源时,通常采用 同步机制协调各个线程的执行,以确保得到正确的结果。
线程安全问题只在多线程环境下才出现,单纯程串行执行不存在此问题。保证高并发场景下的结程安全,可以从以下四个维度考量
5. 数据单线程内可见。 单线程总是安全的。通过限制数据仅在单线程内可见, 可以避免数据被其他结程篡改。最典型的就是线程局部变量,它存储在独立虚拟机枝 帧的局部变量表中,与其他线程毫无瓜葛。 ThreadLocal 就是采用这种方式来实现线 程安全的。
6. 只读对象。 只读对象总是安全的。它的特性是允许复制、拒绝写人。最典 型的只读对象有 String、Integer等。一个对象想要拒绝任何写人,必须要满足以下条件, 使用 final关键字修饰类,避免被继承,使用 privatefinal关键字避免属性被中途修改; 没有任何更新方法;返回值不能可变对象为引用。
7. 线程安全类。 某些线程安全类的内部有非常明确的结程安全机制。比如 StringBuffer就是一个线程安全类,它采用 synchronized关键字来修饰相关方法。
8. 同步与锁机制。 如果想要对某个对象进行并发更新操作,但又不属于上述 三类,需要开发工程师在代码中实现安全的同步机制。虽然这个机制支持的并发场景 很有价值,但非常复杂且容易出现问题。

线程安全的核心理念就是“要么只读,要么加锁”。合理利用好 JDK提供的并发包, 往往能化腐朽为神奇。 Java并发包( java.util.concurrent,JUC )主要分成以下几个类族

  1. 线程同步类。 这些类使线程间的协调更加容易,支持了更加丰富的线程 协调场景,逐步淘汰了使用 Object 的 wait()和 notify()进行同步的方式。主要代表为 CountDownLatch、 Semaphore、 CyclicBarrier 等。
  2. 并发集合类。 集合并发操作的要求是执行速度快,提取数据准。最著名的 类非 ConcurrentHashMap 莫属,它不断地优化,由刚开始的锁分段到后来的 CAS, 不断地提升并发性能。其他还有 ConcurrentSkipListMap、 CopyOnWriteArrayList、 BlockingQueue 等。
  3. 线程管理类。 虽然 Thread 和 ThreadLocal 在 JDKl.O 就已经引入,但是真 正把 Thread 发扬光大的是线程池。根据实际场景的需要,提供了多种创建线程池的快捷方式,如使用 Executors静态工厂或者使用 ThreadPoolExecutor等。另外,通过 ScheduledExecutorService 来执行定时任务。
  4. 锁相关类。 锁以 Lock 接口为核心,派生出在一些实际场景中进行互斥操 作的锁相关类。最有名的是 ReentrantLock。锁的很多概念在弱化,是因为锁的实现 在各种场景中已经通过类库封装进去了。
2.什么是锁
  1. 用并发包中的锁类
  2. 利用同步代码块
3.线程同步
  1. 同步是什么
  2. volatile
  3. 信号量同步
4.线程池
5.ThreadLocal
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值