java-Lock篇之condition.<二>

1.condition

  condition是java.util.concurrent.locks下的接口,Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解

  成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set (wait-set)。其中,

  Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。

class BoundedBuffer {  
   final Lock lock = new ReentrantLock();//锁对象  
   final Condition notFull  = lock.newCondition();//写线程条件   
   final Condition notEmpty = lock.newCondition();//读线程条件   
  
   final Object[] items = new Object[100];//缓存队列  
   int putptr/*写索引*/, takeptr/*读索引*/, count/*队列中存在的数据个数*/;  
  
   public void put(Object x) throws InterruptedException {  
     lock.lock();  
     try {  
       while (count == items.length)//如果队列满了   
         notFull.await();//阻塞写线程,this.wait()  
       items[putptr] = x;//赋值   
       if (++putptr == items.length) putptr = 0;//如果写索引写到队列的最后一个位置了,那么置为0  
       ++count;//个数++  
       notEmpty.signal();//唤醒读线程,this.notify()  
     } finally {  
       lock.unlock();  
     }  
   }  
  
   public Object take() throws InterruptedException {  
     lock.lock();  
     try {  
       while (count == 0)//如果队列为空  
         notEmpty.await();//阻塞读线程,this.wait()  
Object x = items[takeptr];//取值 if (++takeptr == items.length) takeptr = 0;//如果读索引读到队列的最后一个位置了,那么置为0 --count;//个数-- notFull.signal();//唤醒写线程,this,notify() return x; } finally { lock.unlock(); } } }

 演示用synchronized和lock方式使用的两个小例子

使用synchronized的例子

 
public class SynDemo {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
         Q q=new Q ();
         Consumer c=new Consumer(q);
         Producer p=new Producer (q);
         new Thread (c).start();
         new Thread (p).start();
         
    }

}
//消费者线程(读取)
class Consumer implements Runnable
{
    private Q q=null;
    public Consumer (Q q)
    {
        this.q=q;
    }
    public void run ()
    {
         while(true)
         {
             //System.out.println(Thread.currentThread().getName());
            try {
                q.get();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
         }
    }

}
//生产者线程(更改)
class Producer implements Runnable
{
    private Q q=null;
    private int num=1;
    public Producer (Q q)
    {
      this.q=q;
     }
     public void run ()
     {
         while(true)
         {
         
             //System.out.println(Thread.currentThread().getName());
             if(num==1)
             {
                try {
                    q.put("陈奕迅","男");
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
             }
             else if(num==0)
             {
                 try {
                    q.put("王菲","女");
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
             }
         
        num=(num+1)%2;
         }
     }
}
//共同操作的数据Q,由线程对其进行修改,读取,
//因为要修改和读取同步(即两个方法的同步锁为Q对象),且数据在Q内部,所以应具有操作数据的方法
class Q
{
    private String name;
    private String sex;
  private boolean flag=true;//以标志位来控制更改或读取操作。
    //更改的同步方法
    public synchronized void put(String name,String sex) throws InterruptedException
    {
        //默认标志位为true时更改否则等待
        if(!isFlag())
            wait();
      this.name=name;
        this.sex=sex;
       //更改完后换读取,且唤醒读取(为false标志)的线程
        this.flag=false;
        notify();
         System.out.println(Thread.currentThread().getName());
         
    }
  //读取的同步方法
  public synchronized void get() throws InterruptedException
    {
        //默认标志位为flase时读取否则等待
        if(isFlag())
            wait();
        System.out.println(this.name+":"+this.sex);
        //读取完后换更改,且唤醒更改(为true)的线程
        this.flag=true;
        notify();
         System.out.println(Thread.currentThread().getName());
         
    }

    public boolean isFlag()
    {
           return flag;
    }
    public void setFlag(boolean flag)
    {
           this.flag=flag;
    }
    public String getName()
  {
        return name;
    }
    public void setName(String name)
    {
        this.name=name;
    }
  public String getSex()
  {
        return sex;
    }
    public void getSex(String sex)
    {
        this.sex=sex;
    }

}

使用lock例子,只需要修改Q类内部即可

//synchronized 可用Lock代替
//object的wait,notify和notifyAll方法可用condition对象下对应的方法代替。
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;

//共同操作的数据Q,由线程对其进行修改,读取,
//因为要修改和读取同步(即两个方法的同步锁为Q对象),且数据在Q内部,所以应具有操作数据的方法
class Q
{
    private String name;
    private String sex;
  private boolean flag=true;//以标志位来控制更改或读取操作。
  private final  ReentrantLock l=new ReentrantLock();
  private Condition rc=l.newCondition(); //读线程条件
  private Condition wc=l.newCondition();//写线程条件
    //更改的同步方法
    public   void put(String name,String sex) throws InterruptedException
    {
        l.lock();
        try{
        //默认标志位为true时更改否则等待
        while(!isFlag())
            wc.await();
      this.name=name;
        this.sex=sex;
       //更改完后换读取,且唤醒读取(为false标志)的线程
        this.flag=false;
        rc.signal();
         System.out.println(Thread.currentThread().getName());
        }
        finally{
         l.unlock();
        }
    }
  //读取的同步方法
  public   void get() throws InterruptedException
    {
       l.lock();
       try
       {
        //默认标志位为flase时读取否则等待
        while(isFlag())
            rc.await();
        System.out.println(this.name+":"+this.sex);
        //读取完后换更改,且唤醒更改(为true)的线程
        this.flag=true;
        wc.signal();
          System.out.println(Thread.currentThread().getName());
       }
       finally{
       l.unlock();
       }
    }

    public boolean isFlag()
    {
           return flag;
    }
    public void setFlag(boolean flag)
    {
           this.flag=flag;
    }
    public String getName()
  {
        return name;
    }
    public void setName(String name)
    {
        this.name=name;
    }
  public String getSex()
  {
        return sex;
    }
    public void getSex(String sex)
    {
        this.sex=sex;
    }

}

输出结果:

陈奕迅:男
Thread-0
Thread-1
王菲:女
Thread-0
Thread-1
陈奕迅:男
Thread-0
Thread-1
王菲:女


 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。