在java.util.concurrent.locks包中,提供了一些对象。
Lock接口:替代了synchronized同步,将隐式获取锁,释放锁,变成了显示的获取和释放锁。可以由用户来执行。
常见方法:
lock():获取锁。
unlock():释放锁。
注意使用:在查阅api文档时,发现了一个使用技巧:try{需要同步的代码} finally{释放锁}
newCondition():获取监视器对象。
|--ReentrantLock:接口子类。
Condition接口:替代了Object中的监视器的方法。wait notify notifyAll.
如何获取指定锁的监视器对象呢?可以通过Lock接口的newCondition()方法获取。
await():线程等待。会抛出异常。
signal():唤醒线程。
接下来,就使用新的对象和方法将源程序改写。
这时就能完成一方唤醒的肯定是另一方。
class Res
{
private String name;
private boolean flag;
private int count = 0;
private Lock lock = new ReentrantLock();
private Condition setCon = lock.newCondition();
private Condition outCon = lock.newCondition();
public void set(String name)throws InterruptedException
{
lock.lock();
try
{
while(flag)
setCon.await();
this.name = name;
add();
System.out.println(Thread.currentThread().getName()+"----生产----"+name+"::"+count);
flag = true;
outCon.signal();
}
finally
{
lock.unlock();
}
}
public void out()throws InterruptedException
{
lock.lock();
try
{
while(!flag)
outCon.await();
System.out.println(Thread.currentThread().getName()+"....消费...."+name+"::"+count);
flag = false;
setCon.signal();
}
finally
{
lock.unlock();
}
}
public void add()
{
count++;
}
}
class Input implements Runnable
{
private Res r;
Input(Res r)
{
this.r = r;
}
public void run()
{
while(true)
{
try{r.set("商品");}catch(InterruptedException e){}
}
}
}
class Output implements Runnable
{
private Res r;
Output(Res r)
{
this.r = r;
}
public void run()
{
while(true)
{
try{r.out();}catch(InterruptedException e){}
}
}
}
class ResDemo
{
public static void main(String[] args)
{
Res r = new Res();
//创建两个生成者
new Thread(new Input(r)).start();
new Thread(new Input(r)).start();
//创建两个消费者
new Thread(new Output(r)).start();
new Thread(new Output(r)).start();
}
}
|
|