在Java中,Lock是一个接口,它提供了比synchronized关键字更高级的线程同步机制。使用Lock接口可以创建更复杂和灵活的同步结构。
Lock接口的常用实现类有ReentrantLock和ReentrantReadWriteLock,它们提供了可重入的互斥锁和读写锁。
相比synchronized来实现同步,使用Lock实现同步主要有以下差异性:
使用Lock:
创建Lock对象。
// 创建Lock对象
Lock lock = new ReentrantLock();
```
在需要进行同步的代码块中,通过调用`lock()`方法来获取锁。
lock.lock();
try {
// 同步的代码
} finally {
// 在finally块中释放锁,以确保锁的释放
lock.unlock();
}
```
示例代码如下,多种方式进行代码块同步:
package ch12;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* @copyright 2003-2024
* @author qiao wei
* @date 2024-01-10
* @version 1.0
* @brief
* @history
*/
public class SellTicketThread extends Thread {
public SellTicketThread() {
ticket = 0;
lock = new ReentrantLock();
}
@Override
public void run() {
super.run();
// run01();
runUseLock04();
}
private void runUseSynchronized() {
while (true) {
synchronized (SellTicketThread.class) {
if (100 >= ticket) {
++ticket;
// sleep(100);
System.out.println(getName() + "正在卖第" + ticket + "门票");
} else {
break;
}
}
}
}
/**
* @author qiao wei
* @brief 先处理,后break流程。多处使用类Lock的unlock方法。
* @param
* @return
* @throws
* @history
*/
private void runUseLock01() {
while (true) {
if (100 >= ticket) {
lock.lock();
if (100 >= ticket) {
++ticket;
System.out.println(getName() + "正在卖第" + ticket + "门票");
} else {
lock.unlock();
break;
}
lock.unlock();
} else {
// 退出while循环语句。
break;
}
}
}
/**
* @author qiao wei
* @brief 先处理,后break流程。使用try/finally流程处理类Lock的unlock方法。
* @param
* @return
* @throws
* @history
*/
private void runUseLock02() {
while (true) {
if (100 >= ticket) {
try {
lock.lock();
if (100 >= ticket) {
++ticket;
System.out.println(getName() + "正在卖第" + ticket + "门票");
} else {
break;
}
} finally {
// 唯一解锁处。
lock.unlock();
}
} else {
// 退出while循环语句。
break;
}
}
}
/**
* @author qiao wei
* @brief 先break,后处理流程。多处使用类Lock的unlock方法。
* @param
* @return
* @throws
* @history
*/
private void runUseLock03() {
while (true) {
if (100 == ticket) {
break;
} else {
lock.lock();
if (100 == ticket) {
lock.unlock();
// 退出while循环语句。
break;
} else {
++ticket;
System.out.println(getName() + "正在卖第" + ticket + "门票");
}
lock.unlock();
}
}
}
/**
* @author qiao wei
* @brief 先break,后处理流程。使用try/finally流程处理类Lock的unlock方法。
* @param
* @return
* @throws
* @history
*/
private void runUseLock04() {
while (true) {
if (100 == ticket) {
break;
} else {
lock.lock();
try {
if (100 == ticket) {
break;
} else {
++ticket;
System.out.println(getName() + "正在卖第" + ticket + "门票");
}
} finally {
lock.unlock();
}
}
}
}
/**
* @author qiao wei
* @brief 要出售的总票数。
*/
private static int ticket;
/**
* @author qiao wei
* @brief 同步锁。
*/
private static Lock lock;
}
测试验证:
package ch12;
/**
* @copyright 2003-2024
* @author qiao wei
* @date 2024-01-10
* @version 1.0
* @brief
* @history
*/
public class TestSynchronized {
public TestSynchronized() {}
public static void main(String[] args) {
SellTicketThread thread01 = new SellTicketThread();
SellTicketThread thread02 = new SellTicketThread();
SellTicketThread thread03 = new SellTicketThread();
thread01.start();
thread02.start();
thread03.start();
}
}