21道并发编程面试题(10)

package com.wn.lock; import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; /* * 相比java中的锁Locks in java 里lock实现,读写锁更负载一些; * 假设你的程序中涉及到一些共享资源的读和写操作,且写操作没有读操作那么频繁。在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该都允许多个线程能在同时读取共享数据, * 但是如果一个线程想去写这些共享资源,就不应该再有其他线程对该资源进行读或写; * */ public class CacheTest { //创建map集合 static Map<String,Object> map=new HashMap<String,Object>(); //创建读写锁 static ReentrantReadWriteLock rwl=new ReentrantReadWriteLock(); //获取读操作 static Lock r=rwl.readLock(); //获取写操作 static Lock w=rwl.writeLock(); //获取一个key对应的value public static final Object get(String key){ r.lock(); try { System.out.println("正在做读的操作,key:"+key+"开始"); Thread.sleep(100); Object object = map.get(key); System.out.println("正在做读的操作,key:"+key+"结束"); System.out.println(); return object; } catch (InterruptedException e) { e.printStackTrace(); }finally { r.unlock(); } return key; } //设置key对应的value,并返回旧的value public static final Object put(String key,Object value){ w.lock(); try { System.out.println("正在做写的操作,key:"+key+",value:"+value+"开始"); Thread.sleep(100); Object o = map.put(key, value); System.out.println("正在做写的操作,key:"+key+",value:"+value+"结束"); System.out.println(); return o; } catch (InterruptedException e) { e.printStackTrace(); }finally { w.unlock(); } return value; } public static void main(String[] args){ new Thread(new Runnable() { @Override public void run() { for (int i=0;i<3;i++){ CacheTest.put(i+"",i+""); } } }).start(); new Thread(new Runnable() { @Override public void run() { for (int i=0;i<3;i++){ CacheTest.get(i+""); } } }).start(); } }

20.BlockingQueue阻塞队列的实现方式

  阻塞队列(BlockingQueue)是一个支持两个附加操作的队列,这两个附加的操作是:

    在队列为空时,获取元素的线程会等待队列变为非空;

    当队列满时,存储元素的线程会等待队列可用;

  阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器拿元素;

  在java中,BlockingQueue的接口位于java.util.concurrent包中,阻塞队列是线程安全的;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/c628f105a4eead5224f1076e66487750.html