Java多线程-并发编程概念

并行与并发

thread-001.jpg

  • 并发
    • 两个队伍排一个咖啡机
    • 单cpu,多线程
  • 并行
    • 两个队伍排两个咖啡机
    • 多cpu,多线程

进程与线程

  • 进程间不共享内存
  • 线程间共享内存
  • 多线程优点
    • 资源利用率高
      • 比如将IO和逻辑处理分开,IO时还可以处理业务逻辑
    • 某些情况下程序设计更简单
      • 比如读取多个文件,一个线程一个文件,一个线程用于处理
    • 程序响应更快
      • 比如一个监听线程,将处理逻辑分散给其他线程
  • 多线程代价
    • 设计更复杂
      • 比如涉及共享数据时,需要考虑线程安全
    • 上下文切换开销
      • 切换线程需要存储当前线程本地数据和程序指针,是cpu开销
    • 增加资源消耗
      • 多线程需要消耗额外的cpu,内存,以及操作系统资源

竞态条件与临界资源

public class Counter {
    protected long count = 0;
    public void add(long value){
        count += value;   
    }
}
  • 多线程竞争同一资源时,若对资源的访问顺序敏感,就称存在竞态条件
  • 导致竞态条件发生的代码区称作临界区
  • 此处add()方法就是一个临界区,会产生竞态条件
  • 临界区中使用适当的同步可以避免竞态条件

线程安全

  • 允许被多个线程同时执行的代码称作线程安全的代码

// 局部变量:安全
public void someMethod() {
    long threadSafeInt = 0;
    threadSafeInt++;
}
// 局部对象引用:只要引用不作为返回值被别的线程获取,也是安全的
public void someMethod(){
    LocalObject localObject = new LocalObject();
    localObject.callMethod();
    method2(localObject);
}
public void method2(LocalObject localObject){
    localObject.setValue("value");
}
// 对象成员:不安全
public class NotThreadSafe{
    StringBuilder builder = new StringBuilder();
    public add(String text){
        builder.append(text);
    }   
}
  • 线程控制逃逸规则
    • 若资源的创建,使用,销毁都在一个线程内完成,且永远不会脱离该线程控制,则该资源的使用是线程安全的

不可变性

  • 多线程写会引起竞态条件,读则不会

// 此处的value是安全的
public class ImmutableValue{
    private int value = 0;
    public ImmutableValue(int value){
        value = value;
    }
    public int getValue(){
        return value;
    }
}
  • 注意,“不变”(Immutable)和“只读”(Read Only)是不同的
  • 只读只代表不能直接改变,而非不变
  • 比如,一个人的出生日期是“不变”属性,而一个人的年龄便是“只读”属性,但不是“不变”属性

public class ImmutableValue{
    private int value = 0;
    public ImmutableValue(int value){
        value = value;
    }
    public int getValue(){
        return value;
    }
    public ImmutableValue add(int valueToAdd){
        return new ImmutableValue(value + valueToAdd);
    }
}

并发编程模型

  • 概述
    • 并发模型与分布式系统相似性
    • 并发模型类似于分布式系统架构,它们通常可以互相借鉴思想
    • 例如,为工作者们(线程)分配作业的模型一般与分布式系统中的负载均衡比较相似
    • 同样,它们在日志记录、失效转移、幂等性等错误处理技术上也具有相似性
  • 并行工作者
    • 将作业分发给不同工作者,每个工作者完成整个任务
    • 优点
      • 容易理解,增加工作者数量可提高并行度
    • 缺点
      • 共享状态可能会很复杂
      • 共享资源竞争引起串行化问题
      • 共享状态可能被别的线程修改,必要时工作者需不断重读
  • 流水线模型
    • 每个工作者只负责流程的一部分
    • 可以用IO来作为工作者边界
    • 也称为反应器系统或事件驱动系统,工作者对来自系统内外的事件做出反应
    • 系统例子:Vert.x、AKKa、Node.js
    • 模型例子:Actors、Channels
    • 优点
      • 工作者间无需共享状态
      • 工作者无需担心状态被别的线程改写,可以将状态数据留在内存,最后持久化即可
    • 缺点
      • 代码追踪困难,尤其遇到大量回调时
  • 函数式并行模型(Functional Parallelism)
  • 16
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Eddy咸鱼

感谢大佬加鸡蛋~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值