美文网首页面试题
身为JAVA工作者必须了解的实战知识(十三)

身为JAVA工作者必须了解的实战知识(十三)

作者: a_decb | 来源:发表于2017-08-30 19:17 被阅读63次

    一、状态依赖性的管理

    有界缓存实现的基类

    [java]view plaincopy

    print?

    @ ThreadSafe

    publicabstractclassBaseBoundedBuffer {

    @GuardeBy("this")privatefinalE[] buf;

    @GuardeBy("this")privateinttail;

    @GuardeBy("this")privateinthead;

    @GuardeBy("this")privateintcount;

    protectedBaseBoundedBuffer(intcapacity) {

    this.buf = (E[])newObject[capacity];

    }

    protectedsynchronizedfinalvoiddoPut(E E) {

    buf[tail] = E;

    if(++tail == buf.length) {

    tail =0;

    }

    ++count;

    }

    protectedsynchronizedfinalE doTake() {

    E E = buf[head];

    buf[head] =null;

    if(++head == buf.length) {

    head =0;

    }

    --count;

    returnE;

    }

    publicsynchronizedfinalbooleanisFull() {

    returncount == buf.length;

    }

    publicsynchronizedfinalbooleanisEmpty() {

    returncount ==0;

    }

    }

    1 示例:将前提条件的失败传递给调用者

    [java]view plaincopy

    print?

    @ ThreadSafe

    publicclassGrumpyBoundedBufferextendsBaseBoundedBuffer {

    publicGrumpyBoundedBuffer(intsize){

    super(size);

    }

    publicsynchronizedvoidput(V v){

    if(isFull()){

    thrownewBufferFullException ();

    }

    doPut(v);

    }

    publicsynchronizedV take(){

    if(isEmpty())

    thrownewBufferEmptyExeption ();

    returndoTake();

    }

    }

    缓存为空或者已满都不是异常情况,使用者必须要捕获这些异常才能进行正确的处理。

    [java]view plaincopy

    print?

    while(true){

    try{

    V item = buffer.take();

    // 对于item执行一些操作

    break;

    }catch(BufferEmptyException e) {

    Thread. sleep(SLEEP_GRANULARITY );

    }

    }

    2 示例:通过轮询与休眠来实现简单的阻塞

    从上面的代码可以看出,阻塞与出现异常都需要方法的使用者来处理,现在尝试都封装到有界缓存中。

    [java]view plaincopy

    print?

    @ ThreadSafe

    publicclassSleepyBoundedBufferextendsBaseBoundedBuffer {

    publicSleepyBoundedBuffer(intsize) {

    super(size);

    }

    publicvoidput(V v)throwsInterruptedException{

    while(true){

    synchronized(this){

    if(!isFull()){

    doPut(v);

    return;

    }

    }

    Thread.sleep(SLEEP_GRANULARITY);

    }

    }

    publicV take()throwsInterruptedException{

    while(true){

    synchronized(this){

    if(!isEmpty()){

    returndoTake();

    }

    }

    Thread.sleep(SLEEP_GRANULARITY);

    }

    }

    }

    3 条件队列

    不需要使用while(true),改为使用wait、notifyAll

    [java]view plaincopy

    print?

    @ ThreadSafe

    publicclassBoundedBufferextendsBaseBoundedBuffer {

    // 条件谓词:not-full (!isFull())

    // 条件谓词:not-empty (!isEmpty())

    publicBoundedBuffer(intsize) {

    super(size);

    }

    // 阻塞并直道:not-full

    publicsynchronizedvoidput(V v)throwsInterruptedException{

    while(isFull()){

    wait();

    }

    doPut(v);

    notifyAll();

    }

    // 阻塞并直道:not-empty

    publicsynchronizedV take()throwsInterruptedException{

    while(isEmpty()){

    wait();

    }

    V v = doTake();

    notifyAll();

    returnv;

    }

    }

    二、使用条件队列

    1 条件谓词

    要想正确地使用条件队列,关键是找出对象在哪个条件谓词上等待。

    2 过早唤醒

    例如:内置条件队列中有多个条件谓语,此时如果调用notifyAll其含义是通知所有wait,但是并不一定所有条件谓语都满足执行条件。

    当使用条件等待时(例如Object.wait或Condition.await):

    . 通常都有一个条件谓词--包括一些对象状态的测试,线程在执行前必须首先通过这些测试。

    . 在调用wait之前测试条件谓词,并且从wait中返回时再次进行测试。

    . 在一个循环中调用wait。

    . 确保使用与条件队列相关的锁来保护构成条件谓词的各个状态变量。

    . 当调用wait、notify或notifyAll等方法时,一定要持有与条件队列相关的锁。

    . 在检查条件谓词之后以及开始执行相应的操作之前,不要释放锁。

    3 丢失的信号

    已经满足通知的条件发出通知,但是之后才进入阻塞wait状态,所以wait永远等不到在其前面发出的notify。

    4 通知

    5 示例:阀门类

    6 子类的安全问题

    7 封装条件队列

    8 入口协议与出口协议

    三、显式的Condition对象

    四、Synchronizer剖析

    五、AbstractQueuedSynchronizer

    六、java.util.concurrent同步器类中的 AQS

    1 ReentrantLock

    2 Semaphore与CountDownLatch

    3 FutureTask

    4 ReentrantReadWriteLock

    好了同学们,我能介绍的也都全部介绍完给你们了,如果下获得更多JAVA教学资源,可以选择来我们这里共同交流,群:240448376,很多大神在这里切磋学习,不懂可以直接问,晚上还有大牛免费直播教学。

    注:加群要求

    1、具有一定工作经验的,面对目前流行的技术不知从何下手,需要突破技术瓶颈的可以加,有些应届生和实习生也可以加。

    2、在公司待久了,过得很安逸,但跳槽时面试碰壁。需要在短时间内进修、跳槽拿高薪的可以加。

    3、如果没有工作经验,但基础非常扎实,对java工作机制,常用设计思想,常用java开发框架掌握熟练的,可以加。

    4、觉得自己很牛B,一般需求都能搞定。但是所学的知识点没有系统化,很难在技术领域继续突破的可以加。

    5.阿里Java高级大牛直播讲解知识点,分享知识,多年工作经验的梳理和总结,带着大家全面、科学地建立自己的技术体系和技术认知!

    PS:现在主要讲解的内容是(反射原理枚举原理与应用注解原理常用设计模式、正规表达式高级应用、JAVA操作Office原理详解JAVA图像处理技术,等多个知识点的详解和实战)

    6.小号或者小白之类加群一律不给过,谢谢。

    最后,每一位读到这里的网友,感谢你们能耐心地看完。觉得对你有帮助可以给个喜欢!希望在成为一名更优秀的Java程序员的道路上,我们可以一起学习、一起进步

    相关文章

      网友评论

        本文标题:身为JAVA工作者必须了解的实战知识(十三)

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