Lock 为线程加锁解锁,因为多个线程在访问同一个资源时,一个资源不能同时给两个线程进行读写操作. 所以使用线程同步的方式来对资源进行访问限制.
下面来看Lock的用法(使用流程):
1. 创建ReentrantLock对象, 首先,这个ReentrantLock类(重入锁),是一种递归无阻塞的同步机制的一个类.
创建方式如下:
Lock lock = new ReentrantLock();
2. 通过对象来获取Condition对象; Condition是一个多线程协调通信的工具类,使得某个或者某些线程一起等待某个条件,只有当该条件具备时(signal 或者signalAll方法被调用时), 这些线程才会被唤醒,从而重新争夺锁.
Condition的作用是用来唤醒和等待.
Condition b = lock.newCondition();
Condition a = lock.newCondition();
3. 提供线程类,在重写的run方法中按照如下流程来执行:
3.1 lock对象.lock 上锁
3.2 执行该线程要做的内容
3.3 Condition对象.signal()
3.4 Condition对象.await()
3.5 lock对象.unlock 解锁
下面来看一个例程: 该例程的主要目的是打印ABABABABABAB.....
public Test{
Lock lock = new ReentrantLock();
Condition a = lock.newCondition();
Condition b = lock.newCondition();
public static void main(String[] args){
Test t = new Test();
new Thread(t.new T1()).start();
new Thread(t.new T2()).start();
}
class T1 implements Runnable{
@Override
public void run(){
while(true){
//上锁
lock.lock();
System.out.println("A");
b.signal(); // 唤醒B
try{
a.await(); // 暂停
}catch(InterruptedException e){
e.printStackTrace;
}
lock.Unlock(); //解锁
}
}
}
class T2 implements Runnable{
@Override
public void run(){
while(true){
//上锁
lock.lock();
System.out.println("B");
a.signal(); // 唤醒A
try{
b.await(); // 暂停
}catch(InterruptedException e){
e.printStackTrace;
}
lock.Unlock(); //解锁
}
}
}
}
需要注意的一点是:
signal和await一定是不同的对象来调用. 一般使用的有两套: Object.notify()---Object.wait() 和Condition.signal()---Condition.await().