9、读写锁
/*
* 独占锁(写锁) 一次只能被一个线程占有
* 共享锁(读锁) 多个线程可以同时占有
* 读--读 可以共存
* 读--写 不能共存
* 写--写 不能共存
* */
public class ReadWriteLockDemo {
public static void main(String[] args) {
MyCacheLock myCacheLock=new MyCacheLock();
//写入操作
for (int i = 1; i <= 7; i++) {
final int temp=i;
new Thread(()->{
myCacheLock.put(temp+"",temp+"");
},String.valueOf(i)).start();
}
//读取操作
for (int i = 1; i <= 7; i++) {
final int temp=i;
new Thread(()->{
myCacheLock.get(temp+"");
},String.valueOf(i)).start();
}
}
}
//自定义缓存
class MyCacheLock{
private volatile Map<String,Object> map=new HashMap<>();
private ReadWriteLock readWriteLock=new ReentrantReadWriteLock();
public void put(String key,Object value){
readWriteLock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName()+"写入"+key);
map.put(key,value);
System.out.println(Thread.currentThread().getName()+"写入完成 ok");
} catch (Exception e) {
e.printStackTrace();
} finally {
readWriteLock.writeLock().unlock();
}
}
public void get(String key){
readWriteLock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName()+"读取了"+key);
Object o=map.get(key);
System.out.println(Thread.currentThread().getName()+"的value值是"+o);
} catch (Exception e) {
e.printStackTrace();
} finally {
readWriteLock.readLock().unlock();
}
}
}
10、阻塞队列
10.1、关系
什么情况下我们会使用到阻塞队列:多线程并发处理,线程池!
10.2、学会使用队列
添加、移除
四组API
方式 | 抛出异常 | 有返回值,不抛出异常 | 阻塞等待 | 超时等待 |
---|---|---|---|---|
添加 | add | offer | put | offer(“value”, 3, TimeUnit.SECONDS) |
移除 | remove | poll | take | poll(3,TimeUnit.SECONDS) |
判断队列首部 | element | peek |
1、抛出异常
2、不会抛出异常
3、阻塞等待
4、超时
/**
* 抛出异常
*/
public static void test1(){
//队列的大小
ArrayBlockingQueue blockingQueue=new ArrayBlockingQueue<>(3);
//进队列
System.out.println(blockingQueue.add("a"));
System.out.println(blockingQueue.add("b"));
System.out.println(blockingQueue.add("c"));
//,抛出异常
// System.out.println(blockingQueue.add("d"));
//查看队首的元素
System.out.println("队首元素是"+blockingQueue.element());
//出队列
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
// ,抛出异常
//System.out.println(blockingQueue.remove());
}
/**
*有返回值,没有异常
*/
public static void test2(){
ArrayBlockingQueue blockingQueue=new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.offer("aa"));
System.out.println(blockingQueue.offer("bb"));
System.out.println(blockingQueue.offer("cc"));
//false,不抛出异常
// System.out.println(blockingQueue.offer("dd"));
//查看队首的元素
System.out.println("队首元素是"+blockingQueue.peek());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
//null ,不抛出异常
// System.out.println(blockingQueue.poll());
}
/**
* 等待,阻塞 (一直阻塞)
*/
public static void test3() throws InterruptedException {
ArrayBlockingQueue blockingQueue=new ArrayBlockingQueue<>(3);
//一直阻塞
blockingQueue.put("aaa");
blockingQueue.put("bbb");
blockingQueue.put("ccc");
//一直等待,等待队列空位,然后插入队列
// blockingQueue.put("ddd");
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
//一直等待,等队列的新元素出现,然后取出
System.out.println(blockingQueue.take());
}
/**
* 等待,阻塞 (等待超时)
*/
public static void test4() throws InterruptedException {
ArrayBlockingQueue blockingQueue=new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.offer("a4"));
System.out.println(blockingQueue.offer("b4"));
System.out.println(blockingQueue.offer("c4"));
System.out.println(blockingQueue.peek());
//等待 4秒就退出
System.out.println(blockingQueue.offer("d4", 4, TimeUnit.SECONDS));
//取出
System.out.println("========================================");
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
//取,超过 4秒就不等了
System.out.println(blockingQueue.poll(4,TimeUnit.SECONDS));
}
10.3、SynchronousQueue 同步队列
/**
* 同步队列
*/
public class SynchronousQueueDemo {
public static void main(String[] args) {
BlockingQueue<String> blockingQueue =new SynchronousQueue<>();
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName()+" put 001");
blockingQueue.put("1");
System.out.println(Thread.currentThread().getName()+" put 002");
blockingQueue.put("2");
System.out.println(Thread.currentThread().getName()+" put 003");
blockingQueue.put("3");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"T1").start();
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(4);
System.out.println(Thread.currentThread().getName()+" ===> "+blockingQueue.take());
TimeUnit.SECONDS.sleep(4);
System.out.println(Thread.currentThread().getName()+" ===> "+blockingQueue.take());
TimeUnit.SECONDS.sleep(4);
System.out.println(Thread.currentThread().getName()+" ===> "+blockingQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
},"T2").start();
}
}