CountDownLatch简单应用 -- java并发

  网络程序(或在其他异步的程序)由于是异步返回结果的,通常需要阻塞线程直到结果返回,这个时候,下面的代码就有用了。

 

 

 

 

 

package org.jilen.cookie.concurrent;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * This is a simple <strong>future</strong> implementation which <strong>allow
 * client to set value manually</strong>. <br/>
 * All get request are blocked before value is set. <br/>
 * Yes, the <code> new ArrayBlockingQueue(1);</code> can perform the same task.
 * But this version is much more lightweight
 * 
 * @author jilen.zhang@gmail.com
 * @param <V>
 */
public class WaitForValueFuture<V> {

    /**
     * latch used to block before value is set
     */
    private CountDownLatch   latch      = new CountDownLatch(1);
    private volatile boolean isValueSet = false;
   private AtomicBoolean isDone = new AtomicBoolean(false) ;

    /**
     * @return whether the value is set already
     */
    public boolean isDone() {
        return isValueSet;
    }

    /**
     * @return get the value, if value is not set, block until it is set
     * @throws InterruptedException
     */
    public V get() throws InterruptedException {
        latch.await();
        return value;
    }

    /**
     * get the value within specified time
     * 
     * @param timeout
     * @param unit
     * @return
     * @throws InterruptedException
     * @throws TimeoutException
     */
    public V get(long timeout, TimeUnit unit) throws InterruptedException, TimeoutException {
        latch.await(timeout, unit);
        return value;
    }

    /**
     * binding value to this future
     * 
     * @param toBeSet
     */
    public void set(V toBeSet) {
      if(isDone.compareAndSet(false, true)){
          this.value = toBeSet;
          latch.countDown();
        } else {
                throw new IllegalStateException("value is set already");
        }
    }

}
 

 

 

下面是一个silly的使用程序

 

 

package org.jilen.cookie.concurrent;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

public class WaitForValueFutureTest {

    public static void main(String... args) {
        Client sample = new Client();
        Object message = sample.getValueFromSomewhere();
        System.out.println(message);
    }
}

class Client {

    private static Map<Object, WaitForValueFuture<Object>> resultMap   = new ConcurrentHashMap<Object, WaitForValueFuture<Object>>();
    private static AtomicInteger                           idGenerator = new AtomicInteger(0);

    public Object getValueFromSomewhere() {
        //generate a request id, thus after receive response, the value can be set to the future in the result with this key
        Integer requestId = idGenerator.getAndDecrement();
        WaitForValueFuture<Object> future = new WaitForValueFuture<Object>();
        resultMap.put(requestId, future);
        sendGetRequest(requestId, "hello");

        try {
            return future.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //prevent memory leak
            resultMap.remove(requestId);
        }
        return null;
    }

    private void sendGetRequest(Integer requestId, Object message) {
        System.out.println("peformming get request");

        //may be sent request to remote server,just sleep instead
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //within an nio application, this method may be invoke while read event happend
        receiveResponse(requestId, "hello world");
    }

    private void receiveResponse(Integer requestId, Object message) {
        //fill the result
        resultMap.get(requestId).set(message);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值