持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天
1.读写锁
ReadWriteLock
独占锁(写锁)一次只能被一个线程占有
共享锁(读锁) 多个线程可以同时占有
读-读 可以共有
读-写 不能共存
写-写 不能共存
public class ReadWriteLockDemo {
public static void main(String[] args) {
MyCache myCache = new MyCache();
for (int i = 1; i <=5 ; i++) {
final int temp = i ;
new Thread(()->{
myCache.put(temp + "", temp+"");
},String.valueOf(i)).start();
}
for (int i = 1; i <=5 ; i++) {
final int temp = i ;
new Thread(()->{
myCache.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" +key);
} 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()+"读取ok" +key);
} catch (Exception e) {
e.printStackTrace();
} finally {
readWriteLock.readLock().unlock();
}
}
}
class MyCache{
private volatile Map<String ,Object> map = new HashMap<>();
public void put(String key , Object value){
System.out.println(Thread.currentThread().getName()+"写入"+key);
map.put(key, value);
System.out.println(Thread.currentThread().getName()+"写入ok" +key);
}
public void get(String key){
System.out.println(Thread.currentThread().getName()+"读取"+key);
Object o = map.get(key);
System.out.println(Thread.currentThread().getName()+"读取ok" +key);
}
}
2.阻塞队列
阻塞
队列
BlockingQueue
blockingQueue 是Collection的一个子类;
什么情况我们会使用 阻塞队列呢?
操作:添加、移除
但是实际我们要学的有:
四组API
| 方式 | 抛出异常 | 不会抛出异常,有返回值 | 阻塞 等待 | 超时 等待 |
|---|---|---|---|---|
| 添加 | add | offer | put | offer(timenum,timeUnit) |
| 移除 | remove | poll | take | poll(timenum,timeUnit) |
| 判断队列首 | element | peek | - | - |
//抛出异常
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"));
//java.lang.IllegalStateException: Queue full
//System.out.println(blockingQueue.add("d"));
System.out.println("========================");
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
//java.util.NoSuchElementException
//System.out.println(blockingQueue.remove());
}
//有返回值,没有异常
public static void test2(){
//队列大小
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("c"));
System.out.println(blockingQueue.offer("d"));
//java.lang.IllegalStateException: Queue full
//System.out.println(blockingQueue.add("d"));
System.out.println(blockingQueue.peek());
System.out.println("========================");
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
//java.util.NoSuchElementException
//System.out.println(blockingQueue.remove());
}
//等待,阻塞(一直)
public static void test3() throws InterruptedException {
//队列大小
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
blockingQueue.put("a");
blockingQueue.put("a");
blockingQueue.put("a");
//blockingQueue.put("d");
System.out.println(blockingQueue.take());
}
//等待,阻塞(等待超时)
public static void test4() throws InterruptedException {
//队列大小
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("d", 2, TimeUnit.SECONDS));
blockingQueue.poll();
blockingQueue.poll();
blockingQueue.poll();
blockingQueue.poll(2,TimeUnit.SECONDS);
}
SynchornizeQueue 同步队列
没有容量,
进去一个元素,就必须等待去出来之后,才能在往里放一个元素
put,take
public class SynchornizeQueue {
public static void main(String[] args) {
BlockingQueue<String> blockingQueue = new SynchronousQueue<>();// 同步队列
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName()+"put 1");
blockingQueue.put("1");
System.out.println(Thread.currentThread().getName()+"put 2");
blockingQueue.put("2");
System.out.println(Thread.currentThread().getName()+"put 3");
blockingQueue.put("3");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"T1").start();
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+"=>" +blockingQueue.take());
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+"=>" +blockingQueue.take());
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+"=>" +blockingQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
},"T2").start();
}
}