java并发编程第六章(3)使用阻塞式线程安全列表

使用阻塞式线程安全列表

2.使用阻塞式线程安全列表
阻塞式列表与非阻塞式列表的主要区别是:阻塞式列表在插入和删除操作时,如果列表已经满或者已经空了的话,操作不会被立即执行。
而是将调用换这个操作的线程阻塞
直到操作可以执行成功。
本节使用LinkedBlockingDeque类来实现阻塞式列表。
使用方法:
take():从列表中取出字符串,如果列表为空,调用这个方法将被阻塞到列表不为空(即有可用元素)
put():将字符串插入列表中,如果列表已经满(列表生成时指定了固定的容量),调用这个方法的线程将被阻塞直到列表中有可用的元素。
takeFirst(),takeLast():分别返回列表中第一个和最后一个元素,返回的元素会从列表中移除。如果列表为空,
调用方法的线程将被阻塞直到列表中有可用的元素出现。
getFirst(),getLast():分别返回列表中第一个和最后一个元素,返回的元素不会从列表中移除。如果列表为空的话,则抛出NoSuchElementException异常。
peek(),peekFirst(),peekLast():分别返回列表中一个和最后一个元素,返回的元素不会从列表中移除,如果列表为空,返回null。
poll(),pollFirst(),pollLast():分别返回列表中第一个和最后一个元素,返回的元素会从列表中移除,如果列表为空,返回null。
add(),addFirst(),addLast():分别将元素添加到列表中的第一位和最后一位。如果列表已经满,这些方法静抛出IllegalStateException异常。
实例代码:

/**
 * 
 * @author fcs
 * @date 2015-6-21
 * 描述:使用阻塞式线程安全列表
 * 说明:添加大量的数据到一个列表中
 * 
 * 本类使用put()方法将字符串插入到列表中,如果列表(列表生成时指定了容量)已经满的话
 * 调用该方法的线程将被阻塞直到列表中有了可用的空间。
 *
 */
public class Client implements Runnable {

    private LinkedBlockingDeque<String> requestList;

    public Client(LinkedBlockingDeque<String> requestList) {
        this.requestList = requestList;
    }

    @Override
    public void run() {
        for(int i =0;i<3;i++){
            for(int j =0 ;i< 5;j++){
                StringBuilder request = new StringBuilder();
                request.append(i);
                request.append(":");
                request.append(j);
                try {
                    requestList.put(request.toString());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.printf("Client: %s at %s.\n",request,new Date());
            }

            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

/**
 * 
 * @author fcs
 * @date 2015-6-23
 * 描述:该类使用take()方法从列表中取出字符串,如果列表为空,调用这个方法的线程将阻塞直到列表不为空(即有可用元素)
 * 说明:调用这两个方法的线程可能被阻塞,在阻塞是如果线程被中断,方法会抛出InterruptedException异常。
 * 所以必须捕获和处理异常。
 */
public class Main {
    public static void main(String[] args) {
        LinkedBlockingDeque<String> list = new LinkedBlockingDeque<String>(3);
        Client client = new Client(list);
        Thread thread = new Thread(client);
        thread.start();
        for(int i =0;i<5;i++){
            for(int j =0;j<3;j++){
                try {
                    String request = list.take();
                    System.out.printf("Main: request: %s at %s. Size: %d\n",request,new Date(),list.size());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                try {
                    TimeUnit.MILLISECONDS.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println("Main : End of the program.");
    }
}

运行结果
运行截图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值