Lock接口的认识与使用
Lock可以实现与Synchronized同样的功能,需要显示地获取和释放锁,繁琐能让代码更灵活
Synchronized不需要显示地获取和释放锁简单,但是比较重不好控制
使用Lock可以方便的实现公平性,以下例子用ReentrantLock实现一个Lock功能
非阻塞的获取锁
能被中断的获取锁
超时获取锁
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Sequence {
private int value;
Lock lock = new ReentrantLock();
Lock l1 = new ReentrantLock();
/**
* @return
*/
public int getNext() {
lock.lock();
int a = value ++;
lock.unlock();
return a;
}
public static void main(String[] args) {
Sequence s = new Sequence();
new Thread(new Runnable() {
@Override
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName() + " " + s.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() + " " + s.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() + " " + s.getNext());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
自己实现一个锁
使用synchronized 实现Lock接口,实现接口中lock方法和unlock方法
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
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(); // Thread-0
// 第一次线程进来不会被锁,当前线程也不会被锁,第二次如果是同一线程也不锁
while (isLocked && currentThread != lockBy)
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
isLocked = true;//第二次进来如果不是当前线程执行这三行
lockBy = currentThread;
lockCount ++; // 1 2
}
@Override
public synchronized void unlock() {
//如果不是当前线程不执行
if(lockBy == Thread.currentThread()) {
lockCount --; // 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 {
// TODO Auto-generated method stub
return false;
}
@Override
public Condition newCondition() {
// TODO Auto-generated method stub
return null;
}
}
验证锁是否能锁住,可以锁住不会有线程安全性问题
import java.util.concurrent.locks.Lock;
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 s = new Sequence();
new Thread(new Runnable() {
@Override
public void run() {
while(true)
System.out.println(s.getNext());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while(true)
System.out.println(s.getNext());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while(true)
System.out.println(s.getNext());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while(true)
System.out.println(s.getNext());
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while(true)
System.out.println(s.getNext());
}
}).start();
}
}
验证锁是否可重入,下面例子中a,b,c都会被打印证明锁可以重入
import java.util.concurrent.locks.Lock;
public class Demo {
Lock 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();
}
}