大家推荐个靠谱的公众号程序员探索之路,公众号内点击网赚获取彩蛋,大家一起加油,这个公众号已经接入图灵
1.读写互斥
示例: 获取线程获取读锁后,设置线程必须等到读锁释放后才能设置
private static int i = 1;
private static final ReentrantReadWriteLock rw = new ReentrantReadWriteLock();
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("获取开始时间"+System.currentTimeMillis());
getI();
System.out.println("获取结束时间"+System.currentTimeMillis());
}
}).start();
try {
Thread.currentThread().sleep(100);
}catch (Exception e){
//todo 处理异常
}
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("设置开始时间"+System.currentTimeMillis());
setI(2);
System.out.println("设置结束时间"+System.currentTimeMillis());
}
}).start();
}
public static void getI(){
try {
rw.readLock().lock();
Thread.currentThread().sleep(5000);
System.out.println(i);
}catch (Exception e){
//todo 处理异常
} finally {
rw.readLock().unlock();
}
}
public static void setI(int num){
try {
rw.writeLock().lock();
i = num;
}catch (Exception e){
//todo 处理异常
} finally {
rw.writeLock().unlock();
}
}
结果:
获取开始时间1547428797556
设置开始时间1547428797657
1
获取结束时间1547428802558
设置结束时间1547428802558
2.写读互斥
示例: 设置线程获取写锁后,获取线程必须等到写锁释放后才能获取
private static int i = 1;
private static final ReentrantReadWriteLock rw = new ReentrantReadWriteLock();
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("设置开始时间"+System.currentTimeMillis());
setI(2);
System.out.println("设置结束时间"+System.currentTimeMillis());
}
}).start();
try {
Thread.currentThread().sleep(100);
}catch (Exception e){
//todo 处理异常
}
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("获取开始时间"+System.currentTimeMillis());
getI();
System.out.println("获取结束时间"+System.currentTimeMillis());
}
}).start();
}
public static void getI(){
try {
rw.readLock().lock();
System.out.println(i);
}catch (Exception e){
//todo 处理异常
} finally {
rw.readLock().unlock();
}
}
public static void setI(int num){
try {
rw.writeLock().lock();
Thread.currentThread().sleep(5000);
int i = num;
}catch (Exception e){
//todo 处理异常
} finally {
rw.writeLock().unlock();
}
}
结果:
设置开始时间1547428617813
获取开始时间1547428617913
设置结束时间1547428622813
2
获取结束时间1547428622813
3.写写互斥
示例: 可以看到set2释放锁后,set才执行
private static int i = 1;
private static final ReentrantReadWriteLock rw = new ReentrantReadWriteLock();
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("设置2开始时间"+System.currentTimeMillis());
setI2(3);
System.out.println("设置2结束时间"+System.currentTimeMillis());
}
}).start();
try {
Thread.currentThread().sleep(100);
}catch (Exception e){
//todo 处理异常
}
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("设置开始时间"+System.currentTimeMillis());
setI(2);
System.out.println("设置结束时间"+System.currentTimeMillis());
}
}).start();
}
public static void setI2(int num){
try {
rw.writeLock().lock();
Thread.currentThread().sleep(5000);
i = num;
}catch (Exception e){
//todo 处理异常
} finally {
rw.writeLock().unlock();
}
}
public static void setI(int num){
try {
rw.writeLock().lock();
i = num;
}catch (Exception e){
//todo 处理异常
} finally {
rw.writeLock().unlock();
}
}
结果:
设置2开始时间1547429086472
设置开始时间1547429086573
设置2结束时间1547429091473
设置结束时间1547429091473
4.读读不互斥
示例: 可以看到set 不会因为set1获取读锁后睡了5秒而等待,而是立即执行
private static int i = 1;
private static final ReentrantReadWriteLock rw = new ReentrantReadWriteLock();
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("读取2开始时间"+System.currentTimeMillis());
getI2(3);
System.out.println("读取2结束时间"+System.currentTimeMillis());
}
}).start();
try {
Thread.currentThread().sleep(100);
}catch (Exception e){
//todo 处理异常
}
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("读取开始时间"+System.currentTimeMillis());
getI(2);
System.out.println("读取结束时间"+System.currentTimeMillis());
}
}).start();
}
public static void getI2(int num){
try {
rw.readLock().lock();
Thread.currentThread().sleep(5000);
System.out.println("i = "+1);
}catch (Exception e){
//todo 处理异常
} finally {
rw.readLock().unlock();
}
}
public static void getI(int num){
try {
rw.readLock().lock();
System.out.println("i = "+1);
}catch (Exception e){
//todo 处理异常
} finally {
rw.readLock().unlock();
}
}
结果:
读取2开始时间1547429414506
读取开始时间1547429414606
i = 1
读取结束时间1547429414607
i = 1
读取2结束时间1547429419508