Java中的锁

Java SE5之后,并发包中新增Lock接口用来实现锁功能,提供与synchronized关键字类似的同步功能,并且在使用的时候可以显式的获取和释放锁。

实例代码:

Lock lock = new ReentrantLock();  //重入锁
lock.lock(); //获取锁
try{
//
}finally{
lock.unlock(); //释放锁
}

其它接口,

lockInterruptibly()  可中断的获取锁,与lock()方法的不同之处在于该方法会响应中断,即在锁的获取过程中可以中断当前线程。

tryLock()    尝试非阻塞的获取锁。该方法立刻返回,如果能够获取则返回true,否则返回false

tryLock(long time, TimeUnit unit)    超时获取锁。在指定的截止时间之前获取锁,如果截止时间到了仍旧无法获取所,则返回false。

Lock.newCondition() 获取等待通知组件,该组件和锁绑定,当前线程只有获取到了锁,才能调用该组件的wait()方法,而调用后,当前线程将所释放。


import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();

public void await(){
//lock.lock();
try{
lock.lock();
System.out.println("await时间为: " + System.currentTimeMillis());
condition.await();
}catch(InterruptedException e){
            e.printStackTrace();
}finally{
lock.unlock();
}
}

public void siginal(){
try{
lock.lock();
System.out.println("siginal时间为: " + System.currentTimeMillis());
condition.signal();//condition.signalAll();
}finally{
lock.unlock();
}
}

condition.await类似于Object类的wait方法

condition.siginal类似于Object类的notify方法

condition.siginalAll类似于Object类的notifyAll方法

如果需要单独唤醒某个线程,则需要创建多个condition,然后对指定condition唤醒。


利用ReentrantLock实现1对1生产者/消费者模式

public class MyService {

private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private boolean hasValue = false;

public void set() throws InterruptedException{
try{
lock.lock();
System.out.println("set lock begin");
if(hasValue == true){
condition.await();
}
System.out.println("生产一个value");
condition.signal();
hasValue = true;
}finally{
System.out.println("set unlock now");
lock.unlock();
}
}

public void get() throws InterruptedException{
try{
lock.lock();
System.out.println("get lock begin");
if(hasValue == false){
condition.await();
}
System.out.println("消费一个value");
condition.signal();
hasValue=false;
}finally{
System.out.println("get unlock now");
lock.unlock();
}

}

}

//生产者线程

public class MySetThread extends Thread{


private MyService service;

public MySetThread(MyService service){
this.service = service;
}

@Override
public void run() {
try {
for(int i=0;i<5;i++)
    service.set();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

//消费者线程

public class MyGetThread extends Thread{
private MyService service;

public MyGetThread(MyService service){
this.service = service;
}

@Override
public void run() {
try {
for(int i=0;i<5;i++)
service.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}


//测试代码

public static void main(String[] args) {
MyService service = new MyService();
MySetThread a = new MySetThread(service);
a.start();
MyGetThread b = new MyGetThread(service);
b.start();

}


利用ReentrantLock实现多个生产者和消费者的模式

测试代码:

public static void main(String[] args) {
MyService service = new MyService();
MySetThread[] threadSets = new MySetThread[10];
MyGetThread[] threadGets = new MyGetThread[10];

for(int i=0;i<10;i++){
threadSets[i] = new MySetThread(service);
threadGets[i] = new MyGetThread(service);
threadSets[i].start();
threadGets[i].start();
}
}

则需要将之前的condition.singal()改为condition.singalAll()


公平锁与非公平锁

公平锁表示县城获取锁的顺序是按照线程加锁的顺序类分配的,即先来先得的FIFO先进先出顺序。而非公平锁就是一种获取锁的抢占机制,是随机获取锁的。

Lock lock = new ReentrantLock(isFair);




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值