`
raymond.chen
  • 浏览: 1416252 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

ReentrantLock的使用

 
阅读更多

ReentrantLock是一个可重入的互斥锁,又被称为“独占锁”。它添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。

 

ReentrantLock在同一个时间点只能被一个线程获取(当某线程获取到“锁”时,其它线程就必须等待)。

 

ReentrantLock分为“公平锁”和“非公平锁”。在公平锁上,线程按照他们发出请求的顺序获取锁,但在非公平锁上则允许“插队”。

 

ReentraantLock是通过一个FIFO的等待队列来管理获取该锁所有线程的。在“公平锁”的机制下,线程依次排队获取锁;而“非公平锁”在锁是可获取状态时,不管自己是不是在队列的开头都会获取锁。

 

1、防止重复执行(忽略重复触发)

ReentrantLock lock = new ReentrantLock();
if (lock.tryLock()) {  //如果已经被lock,则立即返回false不会等待,达到忽略操作的效果 
	try {
		//操作
	} finally {
		lock.unlock();
	}
}

 

2、同步执行,类似synchronized

ReentrantLock lock = new ReentrantLock(); //参数默认false,不公平锁
ReentrantLock lock = new ReentrantLock(true); //公平锁

lock.lock(); //如果被其它资源锁定,会在此等待锁释放,达到暂停的效果
try {
	//操作
} finally {
    lock.unlock();
}

 

3、尝试等待执行

ReentrantLock lock = new ReentrantLock(true); //公平锁
try {
	if (lock.tryLock(5, TimeUnit.SECONDS)) {  	
		//如果已经被lock,尝试等待5s,看是否可以获得锁,如果5s后仍然无法获得锁则返回false继续执行
		try {
			//操作
		} finally {
			lock.unlock();
		}
	}
} catch (InterruptedException e) {
	e.printStackTrace(); //当前线程被中断时(interrupt),会抛InterruptedException                 
}

 

4、可中断锁的同步执行

ReentrantLock lock = new ReentrantLock(true); //公平锁
lock.lockInterruptibly();
try {
    //操作
} catch (InterruptedException e) {
    e.printStackTrace();
} finally {
    lock.unlock();
}

 

Condition

        Condition是在java1.5中才出现的,它用来替代传统的Object的wait()、notify()实现线程间的协作。相比使用Object的wait()、notify(),使用Condition的await()、signal()这种方式实现线程间协作更加安全和高效。

 

        调用Condition的await()和signal()方法,都必须在lock保护之内。

        Conditon中的await()对应Object的wait(),Condition中的signal()对应Object的notify(),Condition中的signalAll()对应Object的notifyAll()。wait和notify是和synchronized关键字配合使用的。

 

public class MessageService {
	private Lock lock = new ReentrantLock();
    private boolean flag = false;
    private Condition condition = lock.newCondition();
    private int number = 1;
    
    /**
     * 生产者
     */
    public void produce() {
        lock.lock();
        try {
            while (flag == true) {
            	//等待通知进行生产
                condition.await();
            }
            
            System.out.println(Thread.currentThread().getName() + "-----生产-----");
            number++;
            System.out.println("number: " + number);
            TimeUnit.MILLISECONDS.sleep(1000);
            
            flag = true;
            
            //通知进行消费
            condition.signalAll();
            
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    /**
     * 消费者
     */
    public void consume() {
        lock.lock();
        try {
            while (flag == false) {
            	//等待通知进行消费
                condition.await();
            }
            
            System.out.println(Thread.currentThread().getName() + "-----消费-----");
            number--;
            System.out.println("number: " + number);
            TimeUnit.MILLISECONDS.sleep(1000);
            
            flag = false;
            //通知进行生产
            condition.signalAll();
            
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

 

1
3
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics