标签:current exce 示例 其它 ati 优点 上下 inter ted
在ReentrantLock中,可以通过构造函数中的boolean值来指定是否为公平锁,默认是非公平锁,非公平锁的优点在于吞吐量比公平锁大
Lock lock=new ReentrantLock(true);//公平锁
Lock lock1=new ReentrantLock();//非公平锁,默认为false
synchronized是一种非公平锁
代码验证ReentrantLock/synchronized是可重入锁
public class LockDemo2 {
public static void main(String[] args) {
Person person = new Person();
new Thread(() -> {
person.fun1();
}, "t1").start();
new Thread(person, "t2").start();
}
}
class Person implements Runnable {
//fun1,fun2验证synchronized是可重入锁
public synchronized void fun1() {
System.out.println(Thread.currentThread().getName() + "\t invoked fun1");
fun2();
}
public synchronized void fun2() {
System.out.println(Thread.currentThread().getName() + "\t invoked fun2");
}
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
fun3();
}
//验证ReentrantLock是可重入锁
Lock lock = new ReentrantLock();
public void fun3() {
try {
lock.lock();
System.out.println(Thread.currentThread().getName() + "\t invoked fun3");
fun4();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void fun4() {
try {
lock.lock();
System.out.println(Thread.currentThread().getName() + "\t invoked fun4");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
实现一个自旋锁(CAS实现)
/**
* 实现一个自旋锁
* 自旋锁好处:循环比较获取直到成功为止,没有类似wait的阻塞
* <p>
* 通过CAS循环比较的方式完成自旋锁,A线程先获取锁,等待5秒,B线程进来时发现锁被使用,一直循环等待直到A释放锁
*/
public class SpinLockDemo {
AtomicReference<Thread> atomicReference = new AtomicReference<>();
/**
* 获取锁
* 1. 判断原子引用值是否为空
* 2. 若为空,则将原子引用值设置为当前线程
* 3. 若不为空,循环等待值为空
*/
public void myLock() {
Thread thread = Thread.currentThread();
while (!(atomicReference.compareAndSet(null, thread))) {
//自旋锁循环获取锁
System.out.println(thread.getName() + "\t 正在自旋循环尝试获取锁");
}
System.out.println(thread.getName() + "\t lock");
}
/**
* 释放锁
* 1. 将原子引用值设置为空
*/
public void myUnLock() {
Thread thread = Thread.currentThread();
atomicReference.compareAndSet(thread, null);
System.out.println(thread.getName() + "\t unlock");
}
public static void main(String[] args) throws InterruptedException {
SpinLockDemo spinLockDemo = new SpinLockDemo();
new Thread(() -> {
spinLockDemo.myLock();
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
spinLockDemo.myUnLock();
}
}, "A").start();
//保证上面的线程先执行
TimeUnit.SECONDS.sleep(1);
new Thread(() -> {
//5秒之后才能获取到锁
spinLockDemo.myLock();
spinLockDemo.myUnLock();
}, "B").start();
}
}
读写锁代码示例
package com.yls.thread.lock;
import java.util.HashMap;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 当一个线程对某个资源进行写操作时,应该是一个整体(原子+独占),不能被其他线程打断
*/
public class ReadWriteLockDemo {
public static void main(String[] args) throws InterruptedException {
MyCache myCache = new MyCache();
for (int i = 0; i < 5; i++) {
int finalI = i;
new Thread(() -> {
myCache.put(finalI, finalI);
}).start();
}
Thread.sleep(1);
for (int i = 0; i < 5; i++) {
int finalI = i;
new Thread(() -> {
myCache.get(finalI);
}).start();
}
}
}
//模拟缓存
class MyCache {
private HashMap<Integer, Integer> hashMap = new HashMap<>();
private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
//缓存中插入值,使用独占锁
public void put(int key, int value) {
readWriteLock.writeLock().lock();
System.out.println(key + "准备放入:");
hashMap.put(key, value);
System.out.println(key + "放入成功");
readWriteLock.writeLock().unlock();
}
//获取数据,共享锁
public int get(int key) {
readWriteLock.readLock().lock();
System.out.println("准备获取" + key + ":");
int value = hashMap.get(key);
System.out.println(key + "获取成功");
readWriteLock.readLock().unlock();
return value;
}
public void clear() {
hashMap.clear();
}
}
标签:current exce 示例 其它 ati 优点 上下 inter ted
原文地址:https://www.cnblogs.com/yloved/p/11835195.html