您的位置:首页 > 其它

通过Lock对象以及Condition对象实现多线程同步

2014-10-07 21:20 531 查看
在之前的学习中,无论是通过synchronized建立同步代码块,还是通过synchronized建立同步函数,都是把对象看成一把锁来实现同步,这种解释有点牵强,而且在消费者—生产者的那个实例中,其实还有个问题,那就是在避免线程全部冻结时,没必要把相同功能的线程解冻,只要把其他功能的线程解冻即可,也就是说消费者线程只要解冻生产者线程即可,没必要把其他消费者线程也解冻,为了解决这些问题,java1.5版本推出了同步的升级办法,那就是通过Lock对象和Condition对象实现同步。

新的同步办法不再需要synchronized关键字,而引入了更加形象的Lock。

Lock实质上是是一个接口,在创建对象时,使用Lock的子类ReentrantLock来建立对象。

使用方法:建立对象后,在需要同步的代码前一行写 Lock对象.lock(); ,在同步代码后一行写 Lock对象.unlock();

Lock对象用来控制线程的进出,而对线程的操作则由Condition对象来操作;

对应关系:

wait——await(两者均抛出异常)

notify——signal

notifyAll——signalAll

Condition同样是接口,建立方法(比较神奇) Condition 对象名=Lock对象.newCondition();

API上的解释:
Condition
实例实质上被绑定到一个锁上。要为特定
Lock
实例获得
Condition
实例,请使用其
newCondition()
方法。

Condition对象的优势在于,signal只能唤醒被相同Condition对象的await方法冻结的线程,因此,可以建立多个Condition对象,分别用来冻结和解冻不同功能的线程

最后要注意的是,Lock接口属于类包java.util.concurrent.locks,因此,在写代码前,应该先导入类包

上次实例的升级版:

//需求:产品每生产一个消费一个
import java.util.concurrent.locks.*;
class ProducerConsumerDemo
{
public static void main(String[] args)
{
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(con);
Thread t4 = new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();

}
}
class Resource
{
private String name;
private int count = 1;
private boolean flag = false;
Lock lock=new ReentrantLock();
Condition pro = lock.newCondition();
Condition con = lock.newCondition();
public void set(String name)
{
lock.lock();
while(flag)
try{pro.await();}catch(Exception e){}
this.name = name+"--"+count++;
System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
flag = true;
con.signalAll();
lock.unlock();
}
public void out()
{
lock.lock();
while(!flag)
try{con.await();}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);
flag = false;
pro.signalAll();
lock.unlock();
}
}

class Producer implements Runnable
{
private Resource res;

Producer(Resource res)
{
this.res = res;
}
public void run()
{
while(true)
{
res.set("+商品+");
}
}
}

class Consumer implements Runnable
{
private Resource res;

Consumer(Resource res)
{
this.res = res;
}
public void run()
{
while(true)
{
res.out();
}
}
}
注意看Resource类的变化



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐