ReentrantLock同步

来源:互联网 发布:心事谁人知谐音 编辑:程序博客网 时间:2024/06/15 00:31

ReentrantLock加锁和释放锁的一般形式如下

Lock lock = new ReentrantLock();//默认使用非公平锁,如果要使用公平锁,需要传入参数true  ........  lock.lock();  try {       //更新对象的状态      //捕获异常,必要时恢复到原来的不变约束     //如果有return语句,放在这里   finally {         lock.unlock();        //锁必须在finally块中释放        }

实现可中断等待

ReentrantLock可以实现等待中断,当某现在等待时间过长,可以接受中断退出等待,如下所示:

package jalonTest;import java.util.concurrent.locks.ReentrantLock;  /*    write线程一直占有锁不退出,read线程在等待时收到中断可以退出等待*/public class BufferInterruptibly {      private ReentrantLock lock = new ReentrantLock();      public void write() {          lock.lock();          try {              long startTime = System.currentTimeMillis();              System.out.println("开始往这个buff写入数据…");              for (;;)// 模拟要处理很长时间                  {                  if (System.currentTimeMillis()                          - startTime > Integer.MAX_VALUE) {                      break;                  }              }              System.out.println("终于写完了");          } finally {              lock.unlock();          }      }      public void read() throws InterruptedException {          lock.lockInterruptibly();// 注意这里,可以响应中断              try {              System.out.println("从这个buff读数据");          } finally {              lock.unlock();          }      }    public static void main(String args[]) {          BufferInterruptibly buff = new BufferInterruptibly();          final Writer2 writer = new Writer2(buff);          final Reader2 reader = new Reader2(buff);          writer.start();          reader.start();          new Thread(new Runnable() {              public void run() {                  long start = System.currentTimeMillis();                  for (;;) {                      if (System.currentTimeMillis()                              - start > 5000) {                          System.out.println("不等了,尝试中断");                          reader.interrupt();  //此处中断读操作                          break;                      }                  }              }          }).start();      }  }  class Reader2 extends Thread {      private BufferInterruptibly buff;      public Reader2(BufferInterruptibly buff) {          this.buff = buff;      }      @Override      public void run() {          try {              buff.read();//可以收到中断的异常,从而有效退出              } catch (InterruptedException e) {              System.out.println("我不读了");          }          System.out.println("读结束");      }  }  class Writer2 extends Thread {      private BufferInterruptibly buff;      public Writer2(BufferInterruptibly buff) {          this.buff = buff;      }      @Override      public void run() {          buff.write();      }  }

前面提到的synchronized同步则不能实现中断退出!

实现条件变量

package jalonTest;import java.util.concurrent.locks.*;  /*    Producer向缓存中写入类容,内容写入完毕后唤醒等待的Consumer线程*/class Info{ // 定义信息类      private String name = "name";//定义name属性,为了与下面set的name属性区别开      private String content = "content" ;// 定义content属性,为了与下面set的content属性区别开      private boolean flag = true ;   // 设置标志位,初始时先生产      private Lock lock = new ReentrantLock();        private Condition condition = lock.newCondition(); //产生一个Condition对象      public  void set(String name,String content){          lock.lock();          try{              while(!flag){                  condition.await() ;              }              this.setName(name) ;    // 设置名称              Thread.sleep(300) ;              this.setContent(content) ;  // 设置内容              flag  = false ; // 改变标志位,表示可以取走              condition.signal();          }catch(InterruptedException e){              e.printStackTrace() ;          }finally{              lock.unlock();          }      }      public void get(){          lock.lock();          try{              while(flag){                  condition.await() ;              }                 Thread.sleep(300) ;              System.out.println(this.getName() +                   " --> " + this.getContent()) ;              flag  = true ;  // 改变标志位,表示可以生产              condition.signal();          }catch(InterruptedException e){              e.printStackTrace() ;          }finally{              lock.unlock();          }      }      private void setName(String name){          this.name = name ;      }      private void setContent(String content){          this.content = content ;      }      private String getName(){          return this.name ;      }      private String getContent(){          return this.content ;      }  }  class Producer implements Runnable{ // 通过Runnable实现多线程      private Info info = null ;      // 保存Info引用      public Producer(Info info){          this.info = info ;      }      public void run(){          boolean flag = true ;   // 定义标记位          for(int i=0;i<10;i++){              if(flag){                  this.info.set("姓名--1","内容--1") ;    // 设置名称                  flag = false ;              }else{                  this.info.set("姓名--2","内容--2") ;    // 设置名称                  flag = true ;              }          }      }  }  class Consumer implements Runnable{      private Info info = null ;      public Consumer(Info info){          this.info = info ;      }      public void run(){          for(int i=0;i<10;i++){              this.info.get() ;          }      }  }  public class ThreadCaseDemo{    public static void main(String args[]){          Info info = new Info(); // 实例化Info对象          Producer pro = new Producer(info) ; // 生产者          Consumer con = new Consumer(info) ; // 消费者          new Thread(pro).start() ;          //启动了生产者线程后,再启动消费者线程          try{              Thread.sleep(500) ;          }catch(InterruptedException e){              e.printStackTrace() ;          }          new Thread(con).start() ;      }  }  

在synchronized同步文章中利用synchronized实现了类似的功能。synchronized和ReentrantLock最大的差别还是在于高并发性。ReentrantLock对高并发性效率较高!

0 0
原创粉丝点击