Java多线程基础——Lock类
什么是Lock类
Lock类是Java多线程中用来控制并发访问的工具类。与Java的传统的synchronized关键字相比,Lock类具有更强的线程控制能力和更好的性能。
Lock类的使用方法
创建锁对象
在使用Lock对象之前,我们首先需要进行创建。Lock类中有两个最常用的子类:ReentrantLock和ReentrantReadWriteLock.ReadLock/WriteLock。
-
ReentrantLock:一个可重入的互斥锁在使用ReentrantLock实现上要比使用synchronized更加灵活。
-
ReentrantReadWriteLock.ReadLock/WriteLock:一个读写锁中包含读锁和写锁,可以实现读写分离。读锁确保值的可见性,写锁则更改共享状态。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
Lock lock = new ReentrantLock();
获取锁对象
通过lock()方法获取锁对象,该方法会阻塞等待直到获取到锁对象。与synchronized关键字相比,lock()方法可以控制等待时间,并且可以中断等待。
lock.lock(); //获取锁对象,如果锁对象已经被其他线程占用,则一直等待直到获取到锁对象。
释放锁对象
在使用完锁对象之后,需要使用unlock()方法释放锁对象。
lock.unlock(); //释放锁对象
tryLock方法
tryLock()方法尝试获取锁对象,如果获取成功则返回true,否则返回false。与lock()方法不同的是,tryLock()方法不会阻塞线程,它会直接返回。
if (lock.tryLock()) { //尝试获取锁对象,如果获取成功,则执行下面代码
try {
//操作共享资源
} finally {
lock.unlock(); //释放锁对象
}
} else { //获取锁对象失败,处理其他逻辑
...
}
示例
示例一
以下代码展示了Lock类在多线程环境下应用的示例,使用两个线程分别打印奇数和偶数。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class PrintNumber implements Runnable {
private int number;
private Lock lock;
public PrintNumber(int number, Lock lock) {
this.number = number;
this.lock = lock;
}
@Override
public void run() {
try {
lock.lock(); //获取锁对象
System.out.println(Thread.currentThread().getName() + ": " + number);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); //释放锁对象
}
}
}
public class LockDemo {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
//创建两个线程分别用来打印奇数和偶数
Thread oddThread = new Thread(new PrintNumber(1, lock));
Thread evenThread = new Thread(new PrintNumber(2, lock));
oddThread.start();
evenThread.start();
}
}
示例二
以下代码演示了Lock类在多线程环境下实现读写分离的示例。
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
class ListReader implements Runnable {
private List<Integer> list;
private Lock readLock;
public ListReader(List<Integer> list, ReentrantReadWriteLock lock) {
this.list = list;
this.readLock = lock.readLock();
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
readLock.lock(); //获取读锁
int num = list.get(i);
System.out.println(Thread.currentThread().getName() + ": " + num);
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
readLock.unlock(); //释放读锁
}
}
}
}
class ListWriter implements Runnable {
private List<Integer> list;
private Lock writeLock;
public ListWriter(List<Integer> list, ReentrantReadWriteLock lock) {
this.list = list;
this.writeLock = lock.writeLock();
}
@Override
public void run() {
for (int i = 10; i < 15; i++) {
try {
writeLock.lock(); //获取写锁
list.add(i);
System.out.println(Thread.currentThread().getName() + ": " + i);
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
writeLock.unlock(); //释放写锁
}
}
}
}
public class ReadWriteLockDemo {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
//创建两个线程,分别用来读和写一个列表
Thread readThread = new Thread(new ListReader(list, lock));
Thread writeThread = new Thread(new ListWriter(list, lock));
readThread.start();
writeThread.start();
}
}
以上就是Lock类的使用方法和示例,通过学习可以更好的掌握Lock类在多线程中的应用。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程基础——Lock类 - Python技术站