java基础知识回顾之java Thread类学习(八)--java.util.concurrent.locks(JDK1.5)与synchronized异同讲解

看API文档介绍几个方法:

 JDK1.5中提供了多线程的升级解决方案:

           特点: 1.将同步synchronized显示的替换成Lock
                    2.接口Condition:Condition替代了Object监视器方法(wait、notify、notifyAll),分别替换成了await(),signal() (唤醒一个等待线                   程),signalAll() 唤醒多个线程。一个锁可以绑定多个condition对象,可以对应好几组wait,notify,notifyAll动作。

java.util.concurrent.locks接口
 *     Lock接口下面的方法
 *     void lock():获取锁,如果锁不可用,出于线程调度目的,将禁用当前线程,并且在获得锁之前,该线程将一直处于休眠状态。
 *     boolean tryLock():如果获得了锁,返回true。如果别的线程正在持有锁,返回false
 *     boolean tryLock(long time,//等待多长时间获得锁
                TimeUnit unit)
                throws InterruptedException:
       如果获取到锁,立即返回true,如果别的线程正在持有锁,会等待参数给定的时间,如果在这段时间内获得了锁就返回true,如果等待超时,返  回false。

locks的实现类:
      java.lang.Object
             -->java.util.concurrent.locks.ReentrantLock类一个可重入的互斥锁 Lock,替代synchronized,比synchronized有更强大的功能
             -->Java.util.concurrent.locks.ReadWriteLock 提供了一对可供读写并发的锁。
                    

 使用新的锁完成生产者消费者模型:

代码如下:

仓库类(资源)

class ResourceNew{
    private String name;
    private boolean flag = false;
    private int count=1;
    
    private final Lock lock = new ReentrantLock();//将同步synchronized显示的替换成Lock
    private Condition condition_cusumer = lock.newCondition();//同一个锁上可以绑定多个相关的Condition
    private Condition conditon_producer = lock.newCondition();
    
    public  void set(String name) throws InterruptedException{
        try{
            lock.lock();//显示的
            while(flag){
                conditon_producer.await();//生产者等待t1,t2
            }
            this.name = name+"---"+count++;
            System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
            this.flag = true;
//condition.signalAll();//唤醒本方和唤醒对方
            condition_cusumer.signal();//唤醒某个消费者
        }finally{
            lock.unlock();//每个线程进入锁必须要执行的操作,最终要释放锁
        }
    }
    
    public  void out() throws InterruptedException{
        try{
            lock.lock();
            while(!flag){
                condition_cusumer.await();//消费者等待
            }
            System.out.println(Thread.currentThread().getName()+".消费者."+this.name);
            this.flag = false;
            conditon_producer.signalAll();//唤醒生产者
        }finally{
            lock.unlock();
        }
    }
    
}

生产者:

/**
 * 
 * @author Administrator
 * 生产者负责生产,操作同一个资源,但是是生产动作
 *
 */
class producerNew implements Runnable{
    private ResourceNew res;
    public producerNew(ResourceNew res){
        this.res = res;
    }
    public void run() {
        while(true){
            try {
                res.set("..商品..");
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
/**
 * 
 * @author Administrator
 * 消费者负责消费生产者提供的产品,操作的同一个资源,但是是消费动作
 *
 */
class CusumerNew implements Runnable{
    private ResourceNew res;
    public CusumerNew(ResourceNew res){
        this.res = res;
    }
    public void run() {
        while(true){
            try {
                res.out();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

消费者:

/**
 * 
 * @author Administrator
 * 消费者负责消费生产者提供的产品,操作的同一个资源,但是是消费动作
 *
 */
class CusumerNew implements Runnable{
    private ResourceNew res;
    public CusumerNew(ResourceNew res){
        this.res = res;
    }
    public void run() {
        while(true){
            try {
                res.out();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

 synchronized和java.util.concurrent.locks.Lock的异同 :
 * 相同点:Lock能完成synchronized所实现的所有功能。
 * 不同点:1.Lock比Synchonized更精确的线程锁语义和更好的性能。(Synchonized是独占锁,性能不高,而Lock是借助于JNI,性能更高)
 *            2.Lock必须手动释放锁,在finally里面调用unlock()方法释放锁,而synchronized会自动释放锁。

 

 
posted @ 2014-08-22 10:06  积淀  阅读(331)  评论(0编辑  收藏  举报