Lock/Condition/Future示例,基于异步通信的同步机制

Java通过Lock类提供了高级的锁特性,它在获取锁的时候可以做更灵活的控制,比如设置获取锁的最长等待时间。Lock可以与多个Condition对象配合,Lock替代synchronized进行共享对象的锁控制,而Condition替代了Object监控方法的使用,Object中的wait/notify/notifyAll方法,可对应Condition中的await/signal/sinallAll方法。Condition对象一般通过lock.newCondition()方法实例化,所以支持一个lock绑定多个Condition对象进行使用,可实现一个共享对象有多个阻塞集合。使用时需要注意以下规则:

1、object.wait方法调用前必须获取object对象锁,调用wait方法将释放该锁并阻塞线程,直到object.notify/notifyAll方法被调用时才有机会重新获取锁和继续执行;同样的,condition.await方法调用前必须获取关联lock的锁,调用await方法将释放该锁并阻塞线程,直到condition.signal/signalAll方法被调用时才有机会重新获取锁和继续执行;

2、object.notify/notifyAll方法被调用前必须获取到object对象锁,否则会抛异常;同样的,condition.signal/signalAll方法被调用前必须获取关联lock的锁。

Future接口通常用于异步计算场景,比如这样一种场景:底层采用jgroups等异步通信的方式进行远程交互,上层应用依赖底层异步通信的方式给用户提供各种功能。底层是异步通信,而大部分用户功能应该是同步的,如用户点了一个按钮或链接,他期望看到的显示是他上一次操作的结果。该如何搭建基于异步通信的同步机制呢?下面给出一种简单的方案:

1、实现异步消息发送、异步消息接收。

2、异步消息发送后,将发送的消息封装为Future后加入队列待匹配,阻塞线程,直到收到对应的返回结果,或者超时

3、收到异步消息时,在队列中搜索匹配结果,如果匹配ok,将响应内容放到Futrue对象中,同时自动唤醒步骤2中的阻塞点。

以下是参考的Future实现类,实际业务逻辑中,消息发送后,new MsgFutrue(T)构造消息封装对象,加入队列,同时调用future的get方法阻塞线程。在消息接收线程中匹配异步消息对应关系(比如根据sessionID对应),执行步骤3。

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class MsgFuture<T> implements Future<T> {
    
    protected T request;
    private T response;
    
    private ReentrantLock lock;
    private Condition wait;
    
    private volatile boolean done;
    
    public MsgFuture(T request) {
        this.request = request;
        
        lock = new ReentrantLock();
        wait = lock.newCondition();
    }

    @Override
    public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
        if (isDone()) {
            return this.response;
        }
        
        this.lock.lock();
        try {
            this.wait.await(timeout, unit);
        } catch (Exception e) {
//            e.printStackTrace();
        }
        this.lock.unlock();
        
        return this.response;
    }

    @Override
    public T get() throws InterruptedException, ExecutionException {
        this.lock.lock();
        try {
            this.wait.await();
        } catch (Exception e) {
//                e.printStackTrace();
        }
        this.lock.unlock();
        return this.response;
    }
    
    public void done(T respone) {
        this.lock.lock();
        
        this.response = respone;
        this.done = true;
        
        this.wait.signal();
        this.lock.unlock();
    }

    @Override
    public boolean isDone() {
        return done;
    }
    
    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
        return false;
    }

    @Override
    public boolean isCancelled() {
        return false;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值