版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29479041/article/details/84840378
1、认识
2、优势
- Lock 类似于synchronized,具有相同的互斥性和内存可见性,但是更加灵活,加锁和放锁可以由使用者自己确定,Synchronized不需要显示地获取和释放锁,简单
- 可以方便的实行公平性
- 非阻塞的获取锁
- 能被中断的获取锁,synchronized锁可能出现异常而导致中断,无法释放锁,但是通过使用lock,可以直接将lock放在异常finally中,强制释放锁。
- 超时获取锁
3、使用
public class Sequence {
private int value ;
Lock lock = new ReentrantLock();
public int getNext() {
//lock放在这里是锁不住的,所有线程得共用一把锁才锁的住,所有锁得放外边
//Lock lock = new ReentrantLock();
lock.lock();//获取锁
int a = value++;
lock.unlock();//释放锁
return a;
}
public static void main(String[] args) {
Sequence sequence = new Sequence();
//第一个线程
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName()+" ----->"+sequence.getNext());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
//第二个线程
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName()+" ----->"+sequence.getNext());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
//第三个线程
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName()+" ----->"+sequence.getNext());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
4、实现一个普通的锁
public class MyLock implements Lock{
private boolean isLocked = false;
//加锁
@Override
public synchronized void lock() {
// 第一个线程进来不等待,其他线性进来等待
while(isLocked) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
isLocked = true;
}
//释放锁
@Override
public synchronized void unlock() {
isLocked = false;//释放锁
notifyAll();//唤醒其他线程
}
//中断锁
@Override
public void lockInterruptibly() throws InterruptedException {
}
@Override
public boolean tryLock() {
return false;
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return false;
}
@Override
public Condition newCondition() {
return null;
}
}
public class Sequence {
private MyLock lock = new MyLock();
private int value;
public int getNext() {
lock.lock();//获取锁
value++;
lock.unlock();//释放锁
return value;
}
public static void main(String[] args) {
Sequence sequence = new Sequence();
//第一个线程
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName()+" ----->"+sequence.getNext());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
//第二个线程
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName()+" ----->"+sequence.getNext());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
//第三个线程
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName()+" ----->"+sequence.getNext());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
5、实现一个重入锁
public class MyLock implements Lock {
private boolean isLocked = false;//是否锁住
private Thread lockBy = null;//拿到锁的线程
private int lockCount = 0;//锁的数量
@Override
public synchronized void lock() {
Thread currentThread = Thread.currentThread(); // 当前线程
while (isLocked && currentThread != lockBy)//锁住了并且线程不等于当前线程
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
isLocked = true;
lockBy = currentThread;
lockCount ++; // 1 2 3拿到锁的数量想加
}
@Override
public synchronized void unlock() {
if(lockBy == Thread.currentThread()) {
lockCount --; //2 1 0
if(lockCount == 0) {//释放所有锁之后
notify();
isLocked = false;
}
}
}
@Override
public void lockInterruptibly() throws InterruptedException {
}
@Override
public boolean tryLock() {
return false;
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return false;
}
@Override
public Condition newCondition() {
return null;
}
}
public class Demo {
MyLock lock = new MyLock();
public void a() {
lock.lock();
System.out.println("a");
b();
lock.unlock();
}
public void b() {
lock.lock();
System.out.println("b");
c();
lock.unlock();
}
public void c() {
lock.lock();
System.out.println("c");
lock.unlock();
}
public static void main(String[] args) {
Demo d = new Demo();
new Thread(new Runnable() {
@Override
public void run() {
d.a();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
d.b();
}
}).start();
}
}