并发编程总结

并发编程

优势

1.多处理器,充分利用系统资源
2.建模的简单性
3.异步处理,能够灵敏响应

问题

1.竟态性条件:多处理器操作在某个时间段,操作同一个地址,造成数据结果不正确
2.活跃性问题:多线程同步快之间发生相互调用,造成死锁,从而导致后续代码不执行,系统崩溃
3.性能问题:如果线程数量过大,并且线程切换比较频繁,则会造成CPU的使用消耗在上线文切换等操作,造成性能问题
##安全性问题解决
1.保证一个对象是无状态的:即保证一个类中的类变量和实例变量是无状态的。
2.操作是原子操作:对于基本的类型的,JAVA提供了原子变量类来实现基本类型的原子操作,其余的复合操作可以使用锁或者同步块,保证原子操作。
3.锁:锁是保证原子操作的一个重要的实现机制。

  • Lock接口
    • void lock():获取锁,调用该方法当前线程会获取锁
    • void lockInterruptibly(): 可中断的获取锁,在锁的获取中可以中断当前线程
    • boolean tryLock(): 尝试非阻塞的获取锁,调用该方法后立刻返回,如果能获取到则返回true,否则返回false
    • boolean tryLock(long time, TimeUnit unit):查实的获取锁
    • void unlock(): 释放锁
    • Condition newCondition():获取等待通知的组件,该组件和当前的锁绑定,当前线程获取锁然后调用组件的wait()方法,调用后释放锁。
      注意:Lock的主要实现依赖于AbstractQueueSynchronizer,一般在Lock的内部创建静态的队列同步器类
  • 队列同步器
    • getState(): 获取当同步器的状态
    • setState(): 设置当前同步器的状态
    • compareAndSetState(): 对比同步器的状态并设置新的状态,这个是原子操作
  • 重入锁
    • 同步块和ReenTryLock都隐式的使用了重入锁,即当前拥有锁的线程和想要获取锁的线程是同一个线程,则同步器的状态想要的增加,释放时也要多次释放。
  • 读写锁
    • 概述: 读写锁满足同一时刻允许多个线程进行读取,但是在写线程访问时,所有的读线程和写线程均阻塞。
    • 特性:
      a. 公平性选择
      b. 支持重进入
      c. 支持锁降级
    • ReentrantReadWriteLock的接口和示例:
      a. readLock: 获取读锁
      b. wirteLock: 获取写锁
      c. int getReadLockCount(): 返回当前读锁被获取的次数
      d. int getReadHoldCount(): 返回当前线程获取读锁的次数
      e. boolean isWriteLocked(): 判断写锁是否被获取
      f. int getWrieteHoldCount():返回当前写锁被获取的次数。
    • 读写锁的实现:也采用的是队列同步器的实现,需要通过个整型变量来维护多个读线程和一个写线程的状态,采用的是高16位代表读,低16位代表写。
  • LockSupport工具:
    • 概述:LockSupport工具提供了基本的线程阻塞和线程唤醒功能。
      a. void park(): 阻塞当前线程,直到调用unPark(Thread thread)方法或者当前线程被中断才返回。
      b. void parkNanos(long nanos): 阻塞当前线程最长不超过nanos纳秒。
      c. void parkUntil(long deadline): 阻塞当前线程
      d. void unPark(Thread thread): 唤醒处于阻塞状态的线程。
  • Condition接口
    • 概述:Condition接口也提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式(Condition condition =Lock.newCondition();
      注意:Condition接口具有多个队列,并且可以进入等待队列的线程可以不响应中断。
      a. void await(): 当前线程进入等待状态直到被中断或被通知。
      b.void awaitUninterruptibly(): 当前线程进入等待状态直到被通知。
      c. long awaitNanos(long nanos): 当前线程进入等待状态直到被通知、中断和超时。
      d. boolean awaitUtil(Date dealine): 当前线程进入等待状态直到被中断、通知和直到某个时间。
      e. void singal(): 唤醒condition队列等待的状态。
      f. void singalAll(): 唤醒Condition队列上所有等待的状态。