Java ReeantrantLock和条件变量
您好:)我正在学习Java中的重入锁和条件变量。我碰巧遇到这个。在本教程中,作者提供了一个利用ReentrantLock的生产者-消费者示例:Java ReeantrantLock和条件变量,java,multithreading,reentrantlock,Java,Multithreading,Reentrantlock,您好:)我正在学习Java中的重入锁和条件变量。我碰巧遇到这个。在本教程中,作者提供了一个利用ReentrantLock的生产者-消费者示例: public class CondDemo { public static void main(String[] args) { Shared s = new Shared(); new Producer(s).start(); new Consumer(s).start(); } } class
public class CondDemo
{
public static void main(String[] args)
{
Shared s = new Shared();
new Producer(s).start();
new Consumer(s).start();
}
}
class Shared
{
private volatile char c;
private volatile boolean available;
private final Lock lock;
private final Condition condition;
Shared()
{
c = '\u0000';
available = false;
lock = new ReentrantLock();
condition = lock.newCondition();
}
Lock getLock()
{
return lock;
}
char getSharedChar()
{
lock.lock();
try
{
while (!available) {
try
{
condition.await();
}
catch (InterruptedException ie)
{
ie.printStackTrace();
}
}
available = false;
condition.signal();
}
finally
{
lock.unlock();
return c;
}
}
void setSharedChar(char c)
{
lock.lock();
try
{
while (available) {
try
{
condition.await();
}
catch (InterruptedException ie)
{
ie.printStackTrace();
}
}
this.c = c;
available = true;
condition.signal();
}
finally
{
lock.unlock();
}
}
}
class Producer extends Thread
{
private final Lock l;
private final Shared s;
Producer(Shared s)
{
this.s = s;
l = s.getLock();
}
@Override
public void run()
{
for (char ch = 'A'; ch <= 'Z'; ch++)
{
l.lock();
s.setSharedChar(ch);
System.out.println(ch + " produced by producer.");
l.unlock();
}
}
}
class Consumer extends Thread
{
private final Lock l;
private final Shared s;
Consumer(Shared s)
{
this.s = s;
l = s.getLock();
}
@Override
public void run()
{
char ch;
do
{
l.lock();
ch = s.getSharedChar();
System.out.println(ch + " consumed by consumer.");
l.unlock();
}
while (ch != 'Z');
}
}
公共类演示
{
公共静态void main(字符串[]args)
{
共享s=新的共享();
新生产者。开始();
新消费者。开始();
}
}
类共享
{
私有易失性字符c;
可提供私有数据;
私人最终锁;
私人最终条件;
共享()
{
c='\u0000';
可用=错误;
锁=新的可重入锁();
condition=lock.newCondition();
}
Lock getLock()
{
返回锁;
}
char getSharedChar()
{
lock.lock();
尝试
{
而(!可用){
尝试
{
条件wait();
}
捕获(中断异常ie)
{
即printStackTrace();
}
}
可用=错误;
条件。信号();
}
最后
{
lock.unlock();
返回c;
}
}
无效设置共享字符(字符c)
{
lock.lock();
尝试
{
while(可用){
尝试
{
条件wait();
}
捕获(中断异常ie)
{
即printStackTrace();
}
}
这个.c=c;
可用=真实;
条件。信号();
}
最后
{
lock.unlock();
}
}
}
类生成器扩展线程
{
专用最终锁l;
私人最终共享的共享文件;
制作人(共享)
{
这个.s=s;
l=s.getLock();
}
@凌驾
公开募捐
{
对于(char ch='A';ch,这既不是必要的,也不是模式
我觉得这是一个丑陋的冗余锁,过去它的输出是干净的。我的意思是丑陋的,因为没有尝试最终确保一级解锁,它暴露了共享
API的内部状态
为了更深入地学习Java并发,您可以使用或Hmm获得相同的结果,这很奇怪。阅读这段代码,在我看来,锁定的锁可以再次被锁定-这不应该引发异常或什么吗?不,这是锁重入的基础。但是,当获得锁时,必须确保在正确的位置释放锁。但是获得多个锁有什么好处?它可以让您设计不必依赖代码路径的功能。例如,您可以有一个公共方法foo()
,它执行关键代码(因此需要锁),然后它调用另一个公共方法bar()
这两种方法也可以做关键的事情。因为这两种方法都是公共的,所以很难知道在哪种上下文中调用了
。如果您在事务管理方面有一些经验,则应用相同的逻辑。您不知道您的事务是绑定到您的方法还是绑定到更高的调用方。但必须在已打开的相同块级别上释放事务。这不提供问题的答案。批评aut或要求aut澄清hor,在他们的帖子下面留言。我已经说过这只是一个“夸夸其谈”锁所以既不是必需的,也不是模式。我已经明确添加了我的答案。关于如何使用ReentrantLock和条件变量,有更好的例子吗?你看了吗?你也可以看一看。我非常感激。我没有读过它们,但我是著名的,而且是同步的任何应用程序t
/notify
也适用。主要区别在于锁
API不是块绑定的(无论是最坏的还是最好的),通过使用多个条件
实例,您可以拥有多组等待
/通知
。