【Java并发】并发笔记(一)

  • 进程是系统的基本调度单位

  • 多线程的作用:充分发挥多处理器的优势、提高系统性能、提高系统的吞吐率。

  • 多线程的风险:安全性问题(出现不可预料或者错误的值)、活跃性问题(无限循环等)、性能问题(不合理的多线程导致线程切换频繁反而降低性能)


  • 线程安全性:当多线程访问某个类时,这个类始终能表现出正确的行为,那么这个类就是线程安全的。

  • 无状态对象一定是线程安全的。

    有状态就是有数据存储功能。有状态对象(Stateful Bean),就是有实例变量的对象 ,可以保存数据,是非线程安全的。在不同方法调用间不保留任何状态。其实就是有数据成员的对象。

    无状态就是一次操作,不能保存数据。无状态对象(Stateless Bean),就是没有实例变量的对象。不能保存数据,是不变类,是线程安全的。具体来说就是只有方法没有数据成员的对象,或者有数据成员但是数据成员是可读的对象。

    servlet就是一个无状态的对象

  • count++不是个原子操作,它分为3部分:读取、修改和保存

  • 竞态条件:当某个计算的正确性取决于多线程交替执行的时序时,就会产生竞态条件。最常见的就是“先检查后执行”。

  • “先检查后执行”类型的竞态条件:基于一种可能失效的观察结果来做出判断或者执行某个计算。

例如延迟初始化中会发生竞态条件。因为在判断是否存在对象对象引用时,如果有另一个线程同时访问它,则两个线程会返回不同的实例。

  • 延迟加载:目的是为了在需要使用时才创建实例。比如某个系统在启动时会加载大量的类,但是有很多并没有用到,而采取延迟加载则可以提高系统的启动速度。

  • 单例模式:保证多个线程使用到的是同一个实例。

单例模式的写法:

    public static Singleton getInstance(){        
    if (instance == null)        
        synchronized(instance){        
            if(instance == null)        
                instance = new Singleton();        
        }        
    return instance;         
    } 
    首先调用getInstance(),判断instance是否为null,不为null则返回实例,否则将按顺序执行到同步代码块,保证在创建Singleton的时候只有一个线程访问。然后再返回实例。

    //更巧妙的写法
    public class Singleton{        
        private Singleton(){        
            …        
        }        
        private static class SingletonContainer{        
            private static Singleton instance = new Singleton();        
        }        
        public static Singleton getInstance(){        
            return SingletonContainer.instance;        
        }        
    } 

关于单例模式的一篇好文章:

https://www.cnblogs.com/jingpeipei/p/5771716.html

  • Java的内置锁synchronized block(同步代码块),是一种互斥锁,即最多只有一个线程可以持有这个锁。

  • 重入:当一个线程获取由它自己持有的锁时,请求可以成功。

原文地址:https://www.cnblogs.com/cnsec/p/13286715.html