ReadWriteLock

来源:互联网 发布:电脑无法登陆淘宝网 编辑:程序博客网 时间:2024/06/06 04:58

ReentrantLock用法

对象的方法中一旦加入synchronized修饰,则任何时刻只能有一个线程访问synchronized修饰的方法。假设有个数据对象拥有写方法与读方法,多线程环境中要想保证数据的安全,需对该对象的读写方法都要加入 synchronized同步块。这样任何线程在写入时,其它线程无法读取与改变数据;如果有线程在读取时,其他线程也无法读取或写入。这种方式在写入操作远大于读操作时,问题不大,而当读取远远大于写入时,会造成性能瓶颈,因为此种情况下读取操作是可以同时进行的,而加锁操作限制了数据的并发读取。
ReadWriteLock解决了这个问题,当写操作时,其他线程无法读取或写入数据,而当读操作时,其它线程无法写入数据,但却可以读取数据 。

    public class ReadWriteLockDemo {          static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");          public static void main(String[] args) {              Data data = new Data();              Worker t1 = new Worker(data,true);              Worker t2 = new Worker(data,true);              t1.start();              t2.start();          }          static class Worker extends Thread {              Data data;              boolean read;              public Worker(Data data, boolean read) {                  this.data = data;                  this.read = read;              }              public void run() {                  if (read)                      data.get();                  else                      data.set();              }          }          static class Data {              ReadWriteLock lock = new ReentrantReadWriteLock();              Lock read = lock.readLock();              Lock write = lock.writeLock();              public  void set() {                  write.lock();                  System.out.println(Thread.currentThread().hashCode()                          + " set:begin " + sdf.format(new Date()));                  try {                      Thread.sleep(5000);                      //                  } catch (Exception e) {                  } finally {                      System.out.println(Thread.currentThread().hashCode() + " set:end "                              + sdf.format(new Date()));                      write.unlock();                  }              }              public  int get() {                  read.lock();                  System.out.println(Thread.currentThread().hashCode()                          + " get :begin " + sdf.format(new Date()));                  try {                      Thread.sleep(5000);                      //                  } catch (Exception e) {                  } finally {                      System.out.println(Thread.currentThread().hashCode() + " get :end "                              + sdf.format(new Date()));                      read.unlock();                  }                  return 1;              }          }      }  

两个线程均是读线程,结果如下

22474382 get :begin 2011-04-16 18:26:13
4699264 get :begin 2011-04-16 18:26:13
22474382 get :end 2011-04-16 18:26:18
4699264 get :end 2011-04-16 18:26:18

两读线程均可同时读取数据,下面看一个是读线程,一个写线程的情况

Data data = new Data();
Worker t1 = new Worker(data,false);
Worker t2 = new Worker(data,true);

t2.start();
Thread.sleep(100);
t1.start();

先启动读取线程,再启动写入线程,看结果

14718739 get :begin 2011-04-16 18:54:46
14718739 get :end 2011-04-16 18:54:51
14737862 set:begin 2011-04-16 18:54:51
14737862 set:end 2011-04-16 18:54:56

可以看到读取线程工作时,写入线程是不能访问数据的

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 产妇3天没奶水怎么办 产后7天了奶水少怎么办 刚生完小孩没有奶水怎么办 突然就没奶水了怎么办 生完小孩没有奶水怎么办 生完宝宝没有奶怎么办 剖腹产奶涨的疼怎么办 生产一天了没奶怎么办 第一天断奶 奶水一直流出怎么办 新生儿刚出生没奶水怎么办 安卓手机死机了怎么办 婴幼儿几天不拉大便怎么办 樱桃吃多了胃不舒服怎么办 空腹吃水果胃不舒服怎么办 吃水果后胃不舒服怎么办 吃水果伤胃了怎么办 大人吃退烧药不出汗怎么办 稍微吃点凉水果胃就疼怎么办 1岁宝宝感冒发烧怎么办 3岁小儿反复发烧怎么办 热感冒喉咙疼要怎么办 孩子感冒咳嗽嗓子疼怎么办 孕妇感冒了嗓子疼咳嗽怎么办 4岁宝宝反复高烧怎么办 小孩吃完药不退烧怎么办 六个月婴儿发烧怎么办退烧快点 咳嗽20天老不好怎么办 吃过退烧药出汗怎么办 5岁儿童发烧39度怎么办 小孩烧到39度怎么办 儿童7岁发烧39度怎么办 发烧没药怎么办怎样退烧快 小孩发烧怎么办怎样退烧快 发烧头疼怎么办最快最有效 发烧头晕怎么办最快最有效 婴儿发烧怎么办最快最有效 孩子一直37度8怎么办 一岁半宝宝37度5怎么办 发烧打了针35度怎么办 小孩发烧吃了鱼怎么办 八个月婴儿发烧39度怎么办