javareadwritelock的简单介绍

java怎么设置获取读写锁超时时间

1 package bing.test;

2

3 import java.util.concurrent.locks.Lock;

4 import java.util.concurrent.locks.ReadWriteLock;

5 import java.util.concurrent.locks.ReentrantReadWriteLock;

6

7 public class UpgradeLock{

8 private UpgradeLock(){ }

9 private final static ReadWriteLock rwlock =new ReentrantReadWriteLock();

10 private final static Lock read=rwlock.readLock();

11 private final static Lock write=rwlock.writeLock();

12

13

14 public static void main(String[] args){

15 log(getReadLock());

16 log(getWriteLock());

17 }

18

19

20 public static boolean getReadLock()

21 {

22 try{

23 int time = 0;

24 // 设置超时时间为5秒,获取Lock,

25 //如果返回false(即获取失败)则等待直到超时,然后返回获取lock的状态

26 while(!read.tryLock() ++time 5){

27 Thread.sleep(1000);

28 log(time);

29 }

30 return read.tryLock();

31 }catch(Exception e)

32 {

33 e.printStackTrace();

34 return false;

35 }

36 }

37 public static boolean getWriteLock()

38 {

39 try{

40 int time = 0;

41 // 设置超时时间为5秒,获取Lock,

42 //如果返回false(即获取失败)则等待直到超时,然后返回获取lock的状态

43 while(!write.tryLock() ++time 5){

44 Thread.sleep(1000);

45 log(time);

46 }

47 return read.tryLock();

48 }catch(Exception e)

49 {

50 e.printStackTrace();

51 return false;

52 }

53 }

54 public static void log(Object m){

55 System.out.println(m);

56 }

57 }

javareadwritelock的简单介绍

java怎样将数据保存到缓存中,之后再保存

Java中可以使用队列来保存数据,当使用的时候,加上锁,防止其他进程访问,当不用的时候保存到数据库里面,示例如下:

package com.henry;

import java.util.HashMap;

import java.util.Map;

import java.util.Random;

import java.util.concurrent.locks.ReadWriteLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

public class CacheDataTest {

 static MapInteger,Object dataMap=new HashMapInteger,Object();

 static ReadWriteLock lock=new ReentrantReadWriteLock();//创建读写锁的实例

 static Object getData(Integer key){

  lock.readLock().lock();//读取前先上锁

  Object val=null;

  try{

   val=dataMap.get(key);

   if(val == null){

    // Must release read lock before acquiring write lock

    lock.readLock().unlock();

    lock.writeLock().lock();

    try{

     //可能已经由其他线程写入数据

     if(val==null){

      //dataMap.put(key, “”);//query from db

      val=queryDataFromDB(key);

     }

    }finally{

     //Downgrade by acquiring read lock before releasing write lock

     lock.readLock().lock();

     // Unlock write, still hold read

     lock.writeLock().unlock();

    }

   }

  }finally{

   lock.readLock().unlock();//最后一定不要忘记释放锁

  }

  System.out.println(“get data key=”+key+”val=”+val);

  return val;

 }

 

 static Object queryDataFromDB(Integer key){

  Object val=new Random().nextInt(1000);

  dataMap.put(key, val);

  System.out.println(“write into data key=”+key+”val=”+val);

  return val;

 }

 

 public static void main(String[] args) {

  for(int i=0;i10;i++){

   new Thread(new Runnable(){public void run() {

    getData(new Random().nextInt(5));

   }}).start();

  }

 }

}

java readwritelock读写分离吗

读写锁 ReadWriteLock读写锁维护了一对相关的锁,一个用于只读操作,一个用于写入操作。只要没有writer,读取锁可以由多个reader线程同时保持。写入锁是独占的。

互斥锁一次只允许一个线程访问共享数据,哪怕进行的是只读操作;读写锁允许对共享数据进行更高级别的并发访问:对于写操作,一次只有一个线程(write线程)可以修改共享数据,对于读操作,允许任意数量的线程同时进行读取。

与互斥锁相比,使用读写锁能否提升性能则取决于读写操作期间读取数据相对于修改数据的频率,以及数据的争用——即在同一时间试图对该数据执行读取或写入操作的线程数。

读写锁适用于读多写少的情况。

可重入读写锁 ReentrantReadWriteLock

属性ReentrantReadWriteLock 也是基于 AbstractQueuedSynchronizer 实现的,它具有下面这些属性(来自Java doc文档):

* 获取顺序:此类不会将读取者优先或写入者优先强加给锁访问的排序。

* 非公平模式(默认):连续竞争的非公平锁可能无限期地推迟一个或多个reader或writer线程,但吞吐量通常要高于公平锁。

* 公平模式:线程利用一个近似到达顺序的策略来争夺进入。当释放当前保持的锁时,可以为等待时间最长的单个writer线程分配写入锁,如果有一组等待时间大于所有正在等待的writer线程的reader,将为该组分配读者锁。

* 试图获得公平写入锁的非重入的线程将会阻塞,除非读取锁和写入锁都自由(这意味着没有等待线程)。

* 重入:此锁允许reader和writer按照 ReentrantLock 的样式重新获取读取锁或写入锁。在写入线程保持的所有写入锁都已经释放后,才允许重入reader使用读取锁。

writer可以获取读取锁,但reader不能获取写入锁。

* 锁降级:重入还允许从写入锁降级为读取锁,实现方式是:先获取写入锁,然后获取读取锁,最后释放写入锁。但是,从读取锁升级到写入锁是不可能的。

* 锁获取的中断:读取锁和写入锁都支持锁获取期间的中断。

* Condition 支持:写入锁提供了一个 Condition 实现,对于写入锁来说,该实现的行为与 ReentrantLock.newCondition() 提供的Condition 实现对 ReentrantLock 所做的行为相同。当然,此 Condition 只能用于写入锁。

读取锁不支持 Condition,readLock().newCondition() 会抛出 UnsupportedOperationException。

* 监测:此类支持一些确定是读取锁还是写入锁的方法。这些方法设计用于监视系统状态,而不是同步控制。

实现AQS 回顾在之前的文章已经提到,AQS以单个 int 类型的原子变量来表示其状态,定义了4个抽象方法( tryAcquire(int)、tryRelease(int)、tryAcquireShared(int)、tryReleaseShared(int),前两个方法用于独占/排他模式,后两个用于共享模式 )留给子类实现,用于自定义同步器的行为以实现特定的功能。

对于 ReentrantLock,它是可重入的独占锁,内部的 Sync 类实现了 tryAcquire(int)、tryRelease(int) 方法,并用状态的值来表示重入次数,加锁或重入锁时状态加 1,释放锁时状态减 1,状态值等于 0 表示锁空闲。

对于 CountDownLatch,它是一个关卡,在条件满足前阻塞所有等待线程,条件满足后允许所有线程通过。内部类 Sync 把状态初始化为大于 0 的某个值,当状态大于 0 时所有wait线程阻塞,每调用一次 countDown 方法就把状态值减 1,减为 0 时允许所有线程通过。利用了AQS的共享模式。

现在,要用AQS来实现 ReentrantReadWriteLock。

一点思考问题

* AQS只有一个状态,那么如何表示 多个读锁 与 单个写锁 呢?

* ReentrantLock 里,状态值表示重入计数,现在如何在AQS里表示每个读锁、写锁的重入次数呢?

* 如何实现读锁、写锁的公平性呢?

一点提示

* 一个状态是没法既表示读锁,又表示写锁的,不够用啊,那就办成两份用了,客家话说一个饭粒咬成两半吃,状态的高位部分表示读锁,低位表示写锁,由于写锁只有一个,所以写锁的重入计数也解决了,这也会导致写锁可重入的次数减小。

* 由于读锁可以同时有多个,肯定不能再用办成两份用的方法来处理了,但我们有 ThreadLocal,可以把线程重入读锁的次数作为值存在 ThreadLocal 里。

* 对于公平性的实现,可以通过AQS的等待队列和它的抽象方法来控制,在状态值的另一半里存储当前持有读锁的线程数。如果读线程申请读锁,当前写锁重入次数不为 0 时,则等待,否则可以马上分配;如果是写线程申请写锁,当前状态为 0 则可以马上分配,否则等待。

java中读锁的作用,为什么要用读锁

读写锁:ReentrantReadWriteLock

如果有很多线程从一个数据结构中读取数据,而很少的线程修改数据,那么就用读写锁。

分别得到读锁和写锁:

ReentrantReadWriteLock rrwl=new ReentrantReadWriteLock();

ReadLock readL = rrwl.readLock();

WriteLock writeL = rrwl.writeLock();

读锁与读锁不互斥,读锁与写锁互斥,写锁与写锁互斥。

用于优化性能,提高读写速度。

java程序中如何实现对mysql数据库中表的锁定

方法1:用mysql命令锁住表.

public void test() {  

  

    String sql = “lock tables aa1 write”;  

    // 或String sql = “lock tables aa1 read”;   

    // 如果想锁多个表 lock tables aa1 read ,aa2 write , …..   

    String sql1 = “select * from aa1 “;  

  

    String sql2 = “unlock tables”;  

    try {  

        this.pstmt = conn.prepareStatement(sql);  

        this.pstmt1 = conn.prepareStatement(sql1);  

        this.pstmt2 = conn.prepareStatement(sql2);  

        pstmt.executeQuery();  

        pstmt1.executeQuery();  

        pstmt2.executeQuery();  

  

    } catch (Exception e) {  

        System.out.println(“异常” + e.getMessage());  

    }  

  

}

对于read lock 和 write lock官方说明:

1.如果一个线程获得一个表的READ锁定,该线程(和所有其它线程)只能从该表中读取。

如果一个线程获得一个表的WRITE锁定,只有保持锁定的线程可以对表进行写入。

其它的线程被阻止,直到锁定被释放时为止。

2.当您使用LOCK TABLES时,您必须锁定您打算在查询中使用的所有的表。

虽然使用LOCKTABLES语句获得的锁定仍然有效,但是您不能访问没有被此语句锁定的任何的表。

同时,您不能在一次查询中多次使用一个已锁定的表——使用别名代替,

在此情况下,您必须分别获得对每个别名的锁定。

对与read lock 和 write lock个人说明:

1.read lock 和 write lock 是线程级(表级别).

2.在同一个会话中加了read lock锁. 只能对这个表进行读操作.对这个表以外的任何表都无法进行增、删、改、查的操作.

但是在不同会话中,只能对加了read lock的表进行读操作.但可以对read lock以外的表进行增、删、改、查的操作.

3.在同一个会话中加了write lock锁.只能对这个表进行读、写操作.对这个表以外的任何表都无法进行增、删、改、查的操作.

但是在不同会话中,无法对加了write lock的表进行读、写操作.但可以对write lock以外的表进行增、删、改、查的操作.

4.如果表中使用了别名.(SELECT * FROM aa1 AS byname_table)

在对aa1加锁时,必须把别名加上去(lock tables aa1 as byname_table read)

在同一个会话中.必须使用别名进行查询.

在不同的会话中.可以不需要使用别名进行查询.

5.在多个会话中可以对同一个表进行lock read操作.但不能在多个会话中对同一个表进行lock write操作(这些锁将等待已锁的表释放自身的线程锁)

如果多个会话对同一个表进行lock read操作.那么在这些会话中,也只能对以锁的表进行读操作.

6.如果要你锁住了一个表,需要嵌套查询.你必须使用别名,并且,要锁定别名.

例如.lock table aa1 read ,aa1 as byname_table read;

select * from aa1 where id in (select * from aa1 as xx  where id=2);

7.解锁必须用unlock tables;

另:

在JAVA程序中,要想解锁,需要调用 unlock tables来解锁.

如果没有调用unlock tables.

关闭connection 、程序结束 、调用GC 都能解锁.

方法2:用记录锁锁表.

public void test() {  

  

    String sql = “select * from aa1 for update”;   

               // select * from aa1 lock in share mode;   

  

    try {  

        conn.setAutoCommit(false);  

        this.pstmt = conn.prepareStatement(sql);  

        pstmt.executeQuery();  

  

    } catch (Exception e) {  

        System.out.println(“异常” + e.getMessage());  

    }  

  

}

1.for update 与 lock in share mode 属于行级锁和页级锁

2.for update 排它锁,lock in share mode 共享锁

3.对于记录锁.必须开启事务.

4.行级锁定事实上是索引记录的锁定.只要是用索引扫描的行(或没索引全表扫描的行),都将被锁住.

5.在不同的隔离级别下还会使用next-key locking算法.即所扫描的行之间的“间隙”也会也锁住(在Repeatable read和Serializable隔离级别下有间隙锁).

6.在mysql中共享锁的含义是:在被共享锁锁住的行,即使内容被修改且并没有提交.在另一个会话中依然看到最新修改的信息.

在同一会话中加上了共享锁.可以对这个表以及这个表以外的所有表进行增、删、改、查的操作.

在不同的会话中.可以查到共享锁锁住行的最新消息.但是在Read Uncommitted隔离级别下不能对锁住的表进行删,

改操作.(需要等待锁释放才能操作…)

在Read Committed隔离级别下不能对锁住的表进行删,改操作.(需要等待锁释放才能操作…)

在Repeatable read隔离级别下不能对锁住行进行增、删、改操作.(需要等待锁释放才能操作…)

在Serializable隔离级别下不能对锁住行进行增、删、改操作.  (需要等待锁释放才能操作…)

7.在mysql中排他锁的含义是:在被排它锁锁住的行,内容修改并没提交,在另一个会话中不会看到最新修改的信息。

在不同的会话中.可以查到共享锁锁住行的最新消息.但是Read Uncommitted隔离级别下不能对锁住的表进行删,

改操作.(需要等待锁释放才能操作…)

在Read Committed隔离级别下不能对锁住的表进行删,改操作.(需要等待锁释放才能操作…)

在Repeatable read隔离级别下不能对锁住行进行增、删、改操作.(需要等待锁释放才能操作…)

在Serializable隔离级别下不能对锁住行进行增、删、改操作. (需要等待锁释放才能操作…)

8.在同一个会话中的可以叠加多个共享锁和排他锁.在多个会话中,需要等待锁的释放.

9.SQL中的update 与 for update是一样的原理.

10.等待超时的参数设置:innodb_lock_wait_timeout=50 (单位秒).

11.任何可以触发事务提交的命令,都可以关闭共享锁和排它锁.

本文来自投稿,不代表【】观点,发布者:【

本文地址: ,如若转载,请注明出处!

举报投诉邮箱:253000106@qq.com

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2024年3月27日 17:16:02
下一篇 2024年3月27日 17:27:38

相关推荐

  • c语言mallloc使用的简单介绍

    C语言中使用malloc必须加#includemallo.h? 1、在C语言中使用malloc函数进行动态内存分配。malloc的全称是memory allocation,中文叫动态内存分配。原型:extern void malloc(unsigned int num_bytes);功能:分配长度为num_bytes字节的内存块。 2、你可以看一下C语言那本…

    2024年5月23日
    4400
  • javascriptcanvas的简单介绍

    如何使用js在画布上绘制图形 1、可以使用 drawImage()方法把一幅图像绘制到画布上。 以使用三种不同的参数组合。最简单的调用方式是传入一个 HTML 元素,以及绘制该图像的起点的 x 和 y 坐标。 2、效果图:使用JavaScript在画布中绘制文本图形首先我们来看看要在画布上绘制文本图形,需要用到的最重要的属性和方法:font属性:定义文本的字…

    2024年5月23日
    4200
  • cortexm4linux的简单介绍

    Cortex-M4的主要功能 Cortex-M4提供了无可比拟的功能,以将[1] 32位控制与领先的数字信号处理技术集成来满足需要很高能效级别的市场。 Cortex-M4核心具有浮点单元(FPU)单精度,支持所有Arm单精度数据处理指令和数据类型。它还实现了一套完整的DSP指令和一个提高应用程序安全性的内存保护单元(MPU)。 主要是m4比m3多了dsp的支…

    2024年5月23日
    4300
  • 3desjavaphp的简单介绍

    php的3des加密结果与java不一致 他们的加密算法都是通用的,是可以解开的,只要你des的模式,加密长度,初始向量什么的都一样就可以。 JAVA写RSA加密,私钥都是一样的,公钥每次加密的结果不一样跟对数据的padding(填充)有关。Padding(填充)属性定义元素边框与元素内容之间的空间。padding简写属性在一个声明中设置所有内边距属性。 要…

    2024年5月23日
    4700
  • 黑客代码软件学习推荐歌曲的简单介绍

    我想自学编程代码,,目地是“黑”网站,开发出破解代码。有没有这方面的… 这个迭代周期不应该以周为周期或以月为周期发生,而是应该以日为周期。知识等待使用的时间越久,知识这把斧头就越钝。等待学习新知识的时间越长,你就越难以将其融入到代码中。 我认为这个问题问得本身就显得有点矛盾,想学却担心自己看不懂代码学不来,试问哪个编程人员不是从零开始的。坚定信念…

    2024年5月23日
    4700
  • java8种基本类型范围的简单介绍

    java中常用的数据类型有哪些 1、java数据类型分为基本数据类型和引用数据类型,基本数据类型有boolean 、long 、int 、char、byte、short、double、float。引用数据类型有类类型、接口类型和数组类型。 2、java中包含的基本数据类型介绍:\x0d\x0aJava共支持8种内置数据类型。内置类型由Java语言预先定义好,…

    2024年5月23日
    4700
  • linux系统与gpt的关系的简单介绍

    linux下查看分区是不是gpt 看分区会报错,比如:WARNING: GPT (GUID Partition Table) detected on /dev/sda! The util fdisk doesnt support GPT. Use GNU Parted.所以这个sda就是gpt的。 选择“管理”;在“磁盘管理”中,右键“磁盘0”,在弹出的右键…

    2024年5月23日
    5400
  • 北京黑客学习培训的简单介绍

    现在学什么好啊 包括建筑设计、服装设计、珠宝首饰设计等,选择适合自己的设计专业,好好学习,就业容易且收入高。学前教育专业:很多女生喜欢小孩子,且女生一般细心且有耐心,教育行业假期宽裕,工作环境单纯,就业机会多。 现在比较热门好就业的专业有人工智能、机械专业、电子商务专业、人力资源专业、金融学专业、小语种类专业等等。人工智能:人工智能领域的研究包括机器人、语言…

    2024年5月23日
    4100
  • javaee要学那些东西的简单介绍

    java主要学习哪些内容 1、学java最重要的是下面四个内容:掌握Java语言的使用:语言语法、程序逻辑,OOP(面向对象)思想,封装、继承、多态,集合框架、泛型、File I\O技术,多线程技术、socket网络编程,XML技术。 2、Java基础:了解Java的基本语法、数据类型、控制流程、数组、字符串等基础概念。学习面向对象编程(OOP)的原则和概念…

    2024年5月23日
    4200
  • excel自杀的简单介绍

    excel表格中宏代码,具有自杀功能,密码输入错误3次就自动删除表格_百度… 我给楼主一个建议,利用excel自身的密码保护,保护此工作簿的结构,将sheet提前隐藏。这样如果有人将同一份excel打开时,如果不能输入正确的密码,就不能将sheet取消隐藏,就能达到楼主所说的保护了。 如果你还有源文件的话,可以这样试试:打开其他的excel文件,…

    2024年5月23日
    8100

发表回复

登录后才能评论



关注微信