美文网首页
java多线程-1-并发编程

java多线程-1-并发编程

作者: 宠辱不惊的咸鱼 | 来源:发表于2019-09-30 08:58 被阅读0次

    并行与并发

    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)

    相关文章

      网友评论

          本文标题:java多线程-1-并发编程

          本文链接:https://www.haomeiwen.com/subject/msrcpctx.html