Lock锁
锁实现提供了比使用
synchronized
方法和语句更广泛的锁操作。它们允许更灵活的结构,可能有不同的属性,可能支持多个关联的Condition对象。锁是用于控制多个线程对共享资源的访问的工具。
通常,锁提供对共享资源的独占访问:一次只有一个线程可以获得锁,并且所有访问共享资源的访问都需要先获得锁。但是,有些锁可能允许并发访问共享资源。例如readwritellock的读锁。
同步方法或语句的使用提供了对每个对象关联的隐式监视器锁的访问,但强制所有锁的获取和释放都以块结构的方式进行:当多个锁被获取时,它们必须以相反的顺序被释放,并且所有的锁都必须在获取锁的同一个词法作用域中被释放。虽然同步方法和语句的作用域机制使使用监视器锁进行编程变得更加容易,并有助于避免许多涉及锁的常见编程错误,但在某些情况下,您需要以更灵活的方式使用锁。
例如,一些用于遍历并发访问的数据结构的算法需要使用“手拉手”或“链锁”:您获取节点A的锁,然后是节点B,然后释放A并获取C,然后释放B并获取D,等等。
Lock接口的实现允许在不同范围内获取和释放锁,并允许以任何顺序获取和释放多个锁,从而允许使用这种技术。
传统synchronized
synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:
1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
3. 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。
lock.tryLock()
仅在调用时锁是空闲的情况下才获取锁。
- 如果锁可用,则获取锁,并立即返回值为true。
- 如果锁不可用,那么这个方法将立即返回值为false
import org.apache.commons.lang.RandomStringUtils;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class tryLockTest {
private static Lock lock = new ReentrantLock(true);
public static void main(String[] args) {
for (int i = 0; i < 40; i++) {
//启动多个线程进行获取token
new Thread(() -> {
getToke();
}, "a" + i).start();
}
}
private static void getToke(int i) {
if (lock.tryLock()) {
//生成token
String token = RandomStringUtils.randomAlphanumeric(21);
System.out.println(Thread.currentThread().getName() + "-->拿到token:" + token);
//睡眠100毫秒,增加冲突
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(Thread.currentThread().getName() + "-->未拿到token");
}
}
}
执行结果
a1–>未拿到token
a2–>未拿到token
a4–>未拿到token
a5–>未拿到token
a6–>未拿到token
a3–>未拿到token
a7–>未拿到token
a10–>未拿到token
a13–>未拿到token
a31–>未拿到token
a14–>未拿到token
a8–>未拿到token
a9–>未拿到token
a19–>未拿到token
a21–>未拿到token
a26–>未拿到token
a16–>未拿到token
a18–>未拿到token
a24–>未拿到token
a28–>未拿到token
a29–>未拿到token
a30–>未拿到token
a11–>未拿到token
a34–>未拿到token
a35–>未拿到token
a32–>未拿到token
a33–>未拿到token
a37–>未拿到token
a15–>未拿到token
a20–>未拿到token
a38–>未拿到token
a39–>未拿到token
a17–>未拿到token
a23–>未拿到token
a22–>未拿到token
a12–>未拿到token
a36–>未拿到token
a25–>未拿到token
a27–>未拿到token
a0–>拿到token:FFMMDLGi3z7ngKkFG3Nq7