java中锁的底层,Java中Lock锁接口和实现类详解

1. Lock接口

public interface Lock {}

提供更多实用性方法,功能更强大、性能更优越。

常用方法:

① void lock() // 获取锁,如锁被占用,则等待

② boolean trylock() // 尝试获取锁(成功true,失败false,不阻塞)

③ void unlock() // 释放锁

2. ReentrantLock类(重入锁/递归锁) - Lock接口实现类

public class ReentrantLock extends Object implements Lock, Serializable

Lock接口的实现类,与synchronized一样具有互斥锁功能。

注意:

1)使用Lock,需要显式的获取锁和释放锁;

2)为了避免拿到锁的线程在运行期间出现异常,导致程序终止没有释放锁!应用try-finally来保证无论是否出现异常,最终必须释放锁;

3)ReentrantLock为重入锁,避免递归,如果必须递归,必须正确控制退出条件。

(此锁支持同一线程的2147483647个递归锁的最大值。试图在Error超过这个限制的结果将从锁定的方法。)

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

public class TestLocks {

public static void main(String[] args) {

Test obj = new Test();

Thread t1 = new Thread(new MyTask(obj));

Thread t2 = new Thread(new MyTask2(obj));

t1.start();

t2.start();

}

}

class Test{

Lock lock = new ReentrantLock(); // 可重入锁

public void method() {

System.out.println(Thread.currentThread().getName() + "进入上锁的方法中...");

try {

lock.lock(); // 获取锁(显式)

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

//method(); //不要出现无穷递归,容易内存溢出导致锁一直没有释放。

System.out.println(Thread.currentThread().getName() + "退出上锁的方法中...");

} finally {

lock.unlock(); // 释放锁(显式) + 切记finally释放资源

}

}

}

class MyTask implements Runnable {

Test obj;

public MyTask(Test obj) {

super();

this.obj = obj;

}

@Override

public void run() {

obj.method();

}

}

class MyTask2 implements Runnable {

Test obj;

public MyTask2(Test obj) {

super();

this.obj = obj;

}

@Override

public void run() {

obj.method();

}

}

3. ReentrantReadWriteLock类(读写锁) - ReadWriteLock接口实现类

public class ReentrantReadWriteLock extends Object implements ReadWriteLock, Serializable

一种支持一写多读的同步锁,读写分离,可分别分配读锁、写锁;

支持多次分配读锁,使多个读操作可以并发执行(写锁同步,读锁异步)。

互斥规则:

① 写-写:互斥,阻塞;

② 读-写:互斥,读阻塞写、写阻塞读;

③ 读-读:不互斥、不阻塞;

在读操作远远高于写操作的环境下,可在保证线程安全的情况下,提高运行效率。

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.locks.ReentrantReadWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;

import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;

public class TestReadWriteLock {

public static void main(String[] args) {

Student s = new Student();

ExecutorService es = Executors.newFixedThreadPool(20);

WriteTask write = new WriteTask(s);

ReadTask read = new ReadTask(s);

long start = System.currentTimeMillis();

es.submit(write);

es.submit(write);

for (int i = 1; i <= 18; i++) {

es.submit(read);

}

es.shutdown();

while(true) {

System.out.println("结束了吗?");

if (es.isTerminated() == true) {

break;

}

}

long end = System.currentTimeMillis();

System.out.println("运行时间:" + (end-start));

}

}

class WriteTask implements Callable {

Student stu;

public WriteTask(Student stu) {

this.stu = stu;

}

@Override

public Object call() throws Exception {

this.stu.setAge(20);

return null;

}

}

class ReadTask implements Callable {

Student stu;

public ReadTask(Student stu) {

this.stu = stu;

}

@Override

public Object call() throws Exception {

this.stu.getAge();

return null;

}

}

class Student {

private int age;

//Lock lock = new ReentrantLock(); // 读写情况下都加锁,性能过低!

ReentrantReadWriteLock rrwl = new ReentrantReadWriteLock(); // 有两把锁

ReadLock read = rrwl.readLock(); // 读锁 - 内部类

WriteLock write = rrwl.writeLock(); // 写锁 - 内部类

// 赋值:写操作

public void setAge(int age) throws InterruptedException {

//lock.lock();

write.lock();

try {

Thread.sleep(1000);

this.age = age;

} finally {

//lock.unlock();

write.unlock();

}

}

// 取值:读操作

public int getAge() throws InterruptedException {

//lock.lock();

read.lock();

try {

Thread.sleep(1000);

return this.age;

} finally {

//lock.unlock();

read.lock();

}

}

}

// Lock互斥锁运行时间20034毫秒,ReadWriteLock读写锁运行时间3004毫秒

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值