首页 > 学院 > 开发设计 > 正文

ReentrantLock同步

2019-11-09 16:05:53
字体:
来源:转载
供稿:网友

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对高并发性效率较高!


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表