Lock为接口,其实现类为ReetrantLock(可重入锁),其常用方法:
- void lock();不死不休
- boolean tryLock();浅尝辄止
- boolean tryLock(long var1, TimeUnit var3) throws InterruptedException;
- void unlock();
- Condition newCondition();
Condition为接口,其常用方法:
- void await() throws InterruptedException;
- void signal();
获得锁代码示例:
可重入锁的tryLock方法和lock方法
public class GetLock_Demo {
static Lock lock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
lock.lock();//主线程拿到锁
Thread th = new Thread(new Runnable() {
@Override
public void run() {
// boolean rs = false;
// try {
// //boolean rs = lock.tryLock();
// rs = lock.tryLock(1, TimeUnit.SECONDS);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// System.out.println("是否获取到锁:" + rs);
System.out.println("尝试获取锁");
lock.lock();
System.out.println("获得锁了");
}
});
th.start();
Thread.sleep(2000L);//睡眠2秒
th.interrupt();//中断线程运行
System.out.println("th线程中断了");
Thread.sleep(5000L);
lock.unlock();
}
}
执行结果:
尝试获取锁
th线程中断了
获得锁了
Condition的代码示例:
可重入锁的condition用法
public class Condition_Demo {
private static Lock lock = new ReentrantLock();
private static Condition condition = lock.newCondition();
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
try {
System.out.println("当前线程:" + Thread.currentThread().getName() + "获得锁");
condition.await();
System.out.println("当前线程:" + Thread.currentThread().getName() + "开始执行");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
});
thread.start();
Thread.sleep(2000L);
System.out.println("休眠2秒,来控制线程");
lock.lock();
condition.signal();
lock.unlock();
}
}
执行结果:
当前线程:Thread-0获得锁
休眠2秒,来控制线程
当前线程:Thread-0开始执行
自定义阻塞队列之ReentrantLock和Condition
通过ReentrantLock和Condition的锁机制自定义阻塞队列
public class BlockingQueue_Demo {
public static void main(String[] args) throws InterruptedException {
KaneBlockingQueue kaneBlockingQueue = new KaneBlockingQueue(5);
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
kaneBlockingQueue.put("x" + i);
}
}
}).start();
Thread.sleep(1000L);
System.out.println("开始取元素");
for (int i = 0; i < 10; i++) {
kaneBlockingQueue.take();
Thread.sleep(1000L);
}
}
}
class KaneBlockingQueue{
//容器
List<Object> list = new ArrayList<>();
private Lock lock = new ReentrantLock();
private Condition putCondition = lock.newCondition();
private Condition takeCondition = lock.newCondition();
private int length;
public KaneBlockingQueue(int length) {
this.length = length;
}
public void put(Object obj) {
lock.lock();
try {
while (true) {
if (list.size() < length) {
list.add(obj);
System.out.println("队列中放入元素:" + obj);
takeCondition.signal();
return;
} else {//满了,放不进了
putCondition.await();//挂起
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public Object take() {
lock.lock();
try {
if (list.size() > 0) {
Object obj = list.remove(0);
System.out.println("队列中获取的元素:" + obj);
putCondition.signal();
return obj;
} else {
takeCondition.await();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
return null;
}
}
}
执行结果:
队列中放入元素:x0
队列中放入元素:x1
队列中放入元素:x2
队列中放入元素:x3
队列中放入元素:x4
开始取元素
队列中获取的元素:x0
队列中放入元素:x5
队列中获取的元素:x1
队列中放入元素:x6
...
ReentrantLock锁的特性代码示例:
可重入锁ReentrantLock的特性
public class Reetrant_Demo {
static Lock lock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
lock.lock();
System.out.println(Thread.currentThread().getName() + "获得第1次锁");
lock.lock();//可以重入锁多次
System.out.println(Thread.currentThread().getName() + "获得第2次锁");
lock.unlock();//释放不掉
Thread.sleep(1000L);
lock.unlock();
//lock.unlock();//释放多于重入报错
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "开始去获得锁");
lock.lock();
System.out.println("获得锁成功");
lock.unlock();
}
}).start();
}
}
执行结果:
main获得第1次锁
main获得第2次锁
Thread-0开始去获得锁
获得锁成功