- #常用并行API
主要概括Lock、ReadWriteLock、StampedLock与Condition的作用及举例其常见的用法。
@Lock
java.util.concurrent.locks.ReentrantLock作用:实现线程间对于资源竞争的协同工作,可以在实现synchronized关键字功能的基础上进行更多的扩展。如提供的tryLock()方法在无法获取到对象锁时并不会被阻断,这时程序可以去做一些其他事情。
java.util.concurrent.locks.Lock是一个接口(interface),其定义有如下方法:
void lock() 获得锁。
void unlock() 释放锁。
boolean tryLock() 尝试获取锁,获取成功返回true,否则返回false。
Condition newCondition() 创建并返回一个绑定当前Lock对象的Condition对象。(后面会介绍Condition)
--->示例Demo
import static java.lang.System.in;
import static java.lang.System.out;
import java.util.List;
import java.util.LinkedList;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//这是一个非常糟糕的Demo
public class Temp{
public static List<String> list = new LinkedList<String>();
public static Lock lock = new ReentrantLock();
public static int add(String t){
int result = -1;
lock.lock();
try{
list.add(t);
result = list.size() - 1;
}finally{
lock.unlock();
}
return result;
}
public static String get(int t){
String result = null;
lock.lock();
try{
if(list.size()>t)
result = list.remove(t);
}finally{
lock.unlock();
}
return result;
}
public static void main(String... args) throws InterruptedException{
new Thread(()->{
Integer i=0;
while(i<2000){
out.println("add Number '"+i+"' in position:"+Temp.add(i.toString()));
i++;
}
}).start();
new Thread(){
public void run(){
Integer i=-1;
while(++i<2000){
out.println("get Number '"+Temp.get(i)+"' from position:"+i);
}
}
}.start();
}
}
@ReadWriteLock -- 悲观锁
java.util.concurrent.locks.ReadWriteLock作用:实现悲观锁的功能需求。
其有一个实现类java.util.concurrent.locks.ReentrantReadWriteLock,可以通过生成该对象来完成对ReadWriteLock的使用。简介一下悲观锁:多线程背景下,线程对资源的读取操作只有在当前没有写操作进行时才能被允许;线程对资源的读操作只有在当前没有读或写操作时才能被允许。
java.util.concurrent.locks.ReadWriteLock是一个接口(interface),其定义有如下方法:
Lock readLock() 返回用于阅读的锁。
Lock writeLock() 返回用于写入的锁。
--->示例Demo
@StampedLock -- 乐观锁
java.util.concurrent.locks.StampedLock作用:实现乐观锁。
简介一下乐观锁:多线程背景下,某些特殊条件下可能存在读取操作远远多于写入操作的情况,这种情况下悲观锁条件下,如果不加干预,写入操作可能会陷入“饥饿”状态,即写入操作可能一直无法被调用。为了简化处理这类问题的操作,jdk8引入了StampedLock来实现乐观锁的操作。所谓乐观锁,就是乐观地认为,写入与读取同时发生的机会很少,程序可以在读取到数据后检查数据是否遭遇了写入操作的变更,并相应地自定义一些操作。
java.util.concurrent.locks.StampedLock是一个类(class),其定义的常用方法如下:
long readLock() 获取读取锁,并返回一个戳。
long tryOptimisticRead() 标识后面将尝试乐观读取,并返回一个戳。
void unlockRead(long stamp) 通过给定的戳,释放读取锁。
void unlockWrite(long stamp) 通过给定的戳,释放写入锁。
boolean validate(long stamp) 查询给定的戳是否有排他锁定。
long writeLock() 获取写入锁,并返回一个戳。
--->示例Demo
@Condition
Condition作用:将线程收容到一个集合中,进行统一管理。其效果有点类似Object的wait()、notify()等方法所产生的效果。
如何获取一个Condition对象所有操作Lock的类都可以通过newCondition()方法来返回一个与当前Lock对象绑定的Condition对象,并且一个Lock对象可以创建多个Condition对象。
java.util.concurrent.locks.Condition是一个接口(interface),其定义的常用方法如下:
void await() 将当前线程阻断,并置入当前别调用的Condition对象的集合中。
void signal() 随机唤醒一个当前Condition对象所代表的集合中的一个线程。
void signalAll() 唤醒当前Condition对象代表的集合中的所有线程。
--->示例Demo