并发编程---构建自定义的同步工具



1,状态依赖性的管理

  1.1,在单线程程序中,如果某一个基于状态的前提条件未得到满足,则这个条件将永远无法成真,可是,在并发程序中,基于状态的条件可能由于其他线程的操作而改变

2,条件队列

  2.1,他使得一组线程能够通过某种方式来等待特定的条件变为真。传统队列的元素是一个一个数据,而条件队列中的元素是一个一个正在等待相关条件的线程

  2.2,Object.wait会自动释放锁,并请求操作系统挂起当前线程,从而使其他线程能够获得这个锁并修改对象的状态,当被挂起的线程唤醒来时,它将在返回之前重新获取锁
“等待由状态构成的条件”与“维护状态一致性”这两种机制必须被紧密地绑定在一起,只有能对状态进行检查时,才能在某个条件上等待,并且只有能修改状态时,才能从条件等待中释放另一个线程
3,使用条件队列

  3.1,条件谓词:要想正确的使用条件队列,关键是找出对象在哪个条件谓词上等待,条件谓词是使某个操作成为状态依赖操作的前提条件。
  3.2,每一次wait调用都会隐式地与特定的条件谓词关联起来,当调用某个特定条件谓词的wait时,调用者必须已经持有与条件队列相关的锁,并且这个锁必须保护着构成条件谓词的状态变量
  3.3,过早唤醒:当一个wait被唤醒后,并不一定代表他的等待条件已经为真,也可能为真,但是在本线程获取锁之前,已经由其他线程修改了状态。特别是当一个谓词由多个条件组成时,这种唤醒后条件谓词不为真的情况很常见,因此每当线程从wait唤醒后必须再次测试条件谓词。
  3.4,丢失的信号,指的是线程必须等待一个已经为真的条件,和死锁或活锁一样,丢失的信号也是一种形式的活跃性故障。
  3.5,通知,每当等待一个条件时,一定要确保在条件谓词变为真时通过某种方式发出通知。并且发出通知的线程应该尽快地释放锁,从而确保正在等待的线程尽可能快地解除阻塞。如果使用notify而不是notifyAll,那么将是一种危险的操作,因为单一的通知很容易导致类似于信号丢失的问题,虽然notify比notifyAll更低效,但却更容易确保类的行为时正确的。
4,显式的Condition对象,正如Lock是一种广义的内置锁,Condition也是一种广义的内置条件队列。
  4.1,如果想编写一个带有多个条件谓词的并发对象,或者想获得除了条件队列可见性之外的更多控制权,就可以使用显式的Lock和Condition而不是内置锁和条件队列,这是一中更灵活的选择
  4.2,在Condition对象中,与wait,notify,notifyAll方法对应的分别是await,signal,signalAll。
5,AQS
  5.1,AbstractQueuedSynchrogazer(AQS)是一个用于构建锁和同步器的框架,许多同步器都可以通过AQS很容易并且高效地构建出来,包括ReentrantLock,Semaphore,CountDownLatch,ReantrantReadWriteLcok,SynchronousQueue和FutureTask。
  5.2,AQS负责管理同步容器类中的状态,它管理了一个整数状态信息,可以通过getState,setState以及compareAndSetState等protected类型的方法来进行操作。

猜你喜欢

转载自blog.csdn.net/qq_40182703/article/details/80961795