码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • ReadWriteLock(读写锁)和阻塞队列BlockingQueue与同步队列SynchronousQueue


    1.ReadWriteLock

    1. package com.kuang.rw;
    2. import java.util.HashMap;
    3. import java.util.Map;
    4. import java.util.concurrent.locks.ReadWriteLock;
    5. import java.util.concurrent.locks.ReentrantReadWriteLock;
    6. /**
    7. * 独占锁(写锁) 一次只能被一个线程占有
    8. * 共享锁(读锁) 一次能被多个线程占有
    9. * ReadWriteLock 只对put加锁,读写不互斥,会出现脏读,幻读情况
    10. * 读-读 可以共存!
    11. * 读-写 不能共存!
    12. * 写-写 不能共存!
    13. */
    14. public class ReadWriteLockDemo {
    15. public static void main(String[] args) {
    16. MyCacheLock myCache = new MyCacheLock();
    17. for (int i = 0; i < 5; i++) {
    18. int finalI = i;
    19. new Thread(()->{
    20. myCache.put(finalI+"",finalI+"");
    21. },String.valueOf(i)).start();
    22. }
    23. for (int i = 0; i < 5; i++) {
    24. int finalI = i;
    25. new Thread(()->{
    26. myCache.get(finalI+"");
    27. },String.valueOf(i)).start();
    28. }
    29. }
    30. }
    31. /**
    32. * 自定义缓存
    33. *
    34. */
    35. //加了锁的
    36. class MyCacheLock{
    37. private volatile Map map =new HashMap<>();
    38. private ReadWriteLock lock =new ReentrantReadWriteLock();
    39. //存,写 只希望同时只有一个线程写
    40. public void put(String key,Object value){
    41. lock.writeLock().lock();
    42. try {
    43. System.out.println(Thread.currentThread().getName()+"写入开始");
    44. map.put(key,value);
    45. System.out.println(Thread.currentThread().getName()+"写入完成");
    46. } catch (Exception e) {
    47. e.printStackTrace();
    48. } finally {
    49. lock.writeLock().unlock();
    50. }
    51. }
    52. //取,读 读写分离,读写互斥,读读不互斥,写写互斥
    53. public void get(String key){
    54. lock.readLock().lock();
    55. try {
    56. System.out.println(Thread.currentThread().getName()+"读取开始"+key);
    57. Object o = map.get(key);
    58. System.out.println(Thread.currentThread().getName()+"读取完成"+o);
    59. } catch (Exception e) {
    60. e.printStackTrace();
    61. } finally {
    62. lock.readLock().unlock();
    63. }
    64. }
    65. }
    66. class MyCache{
    67. private volatile Map map =new HashMap<>();
    68. //存,写
    69. public void put(String key,Object value){
    70. System.out.println(Thread.currentThread().getName()+"写入开始");
    71. map.put(key,value);
    72. System.out.println(Thread.currentThread().getName()+"写入完成");
    73. }
    74. //取,读
    75. public void get(String key){
    76. System.out.println(Thread.currentThread().getName()+"读取开始"+key);
    77. map.get(key);
    78. System.out.println(Thread.currentThread().getName()+"读取完成");
    79. }
    80. }

     2.阻塞队列BlockingQueue

    BlockingQueue 不是新的东西

    什么情况下我们会使用阻塞队列: 

    多线程并发处理,线程池!

     

    方式      抛出异常有返回值,不抛出异常阻塞等待超时等待
    添加add()offer()put()
    offer("d",2, TimeUnit.SECONDS);
    
    移出remove()poll()take()
    poll(2,TimeUnit.SECONDS)
    
    检测队首元素element()peek()

     2.1抛异常的

    1. /**
    2. * 抛出异常
    3. *
    4. */
    5. public static void test1(){
    6. //队列的大小
    7. ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
    8. System.out.println(blockingQueue.add("a"));
    9. System.out.println(blockingQueue.add("b"));
    10. System.out.println(blockingQueue.add("c"));
    11. /*
    12. java.lang.IllegalStateException: Queue full 抛出异常 !
    13. System.out.println(blockingQueue.add("d"));
    14. */
    15. System.out.println("=======================");
    16. System.out.println(blockingQueue.remove());
    17. System.out.println(blockingQueue.remove());
    18. System.out.println(blockingQueue.remove());
    19. /*
    20. Exception in thread "main" java.util.NoSuchElementException 抛出异常 !
    21. System.out.println(blockingQueue.remove());
    22. */
    23. }
    24. 2.2 有返回值,不抛出异常

      1. /**
      2. * 有返回值,不抛出异常!
      3. */
      4. public static void test2(){
      5. //队列的大小
      6. ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
      7. System.out.println(blockingQueue.offer("a"));
      8. System.out.println(blockingQueue.offer("b"));
      9. System.out.println(blockingQueue.offer("c"));
      10. // System.out.println(blockingQueue.offer("d"));//false 不抛出异常!
      11. System.out.println("==============");
      12. System.out.println(blockingQueue.poll());
      13. System.out.println(blockingQueue.poll());
      14. System.out.println(blockingQueue.poll());
      15. System.out.println(blockingQueue.poll());//null 不抛出异常
      16. }
      17. 2.3 等待,一直阻塞

        1. /**
        2. * 等待,阻塞(一直)
        3. */
        4. public static void test3() throws InterruptedException {
        5. //队列的大小
        6. ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
        7. //一直阻塞
        8. blockingQueue.put("a");
        9. blockingQueue.put("b");
        10. blockingQueue.put("c");
        11. // blockingQueue.put("d");//队列没有位置了
        12. System.out.println(blockingQueue.take());
        13. System.out.println(blockingQueue.take());
        14. System.out.println(blockingQueue.take());
        15. System.out.println(blockingQueue.take());// 没有这个元素,一直阻塞
        16. }
        17. 2.4 等待阻塞, 超时就解除阻塞

          1. /**
          2. * 等待,阻塞(等待超时)
          3. */
          4. public static void test4() throws InterruptedException {
          5. //队列的大小
          6. ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
          7. System.out.println(blockingQueue.offer("a"));
          8. System.out.println(blockingQueue.offer("b"));
          9. System.out.println(blockingQueue.offer("c"));
          10. // blockingQueue.offer("d",2, TimeUnit.SECONDS);//等待超过2秒就退出
          11. System.out.println("==================");
          12. System.out.println(blockingQueue.poll());
          13. System.out.println(blockingQueue.poll());
          14. System.out.println(blockingQueue.poll());
          15. System.out.println(blockingQueue.poll(2,TimeUnit.SECONDS));//等待超过两秒就不阻塞了,就往下继续执行!
          16. System.out.println("结束");
          17. }
          18. 3.同步队列SynchronousQueue

            1. package com.kuang.blockQueue;
            2. import java.util.concurrent.BlockingQueue;
            3. import java.util.concurrent.SynchronousQueue;
            4. import java.util.concurrent.TimeUnit;
            5. /**
            6. * 同步队列
            7. * 和其他的BlockingQueue 不一样 ,SynchronousQueue不存储元素
            8. * put了一个元素,必须从里面先take取出来,否则不能在put进去值
            9. */
            10. public class SynchronousQueueDemo {
            11. public static void main(String[] args) {
            12. BlockingQueue blockingQueue = new SynchronousQueue<>();//同步队列
            13. new Thread(()->{
            14. try {
            15. System.out.println(Thread.currentThread().getName()+"put1");
            16. blockingQueue.put("1");
            17. System.out.println(Thread.currentThread().getName()+"put2");
            18. blockingQueue.put("2");
            19. System.out.println(Thread.currentThread().getName()+"put3");
            20. blockingQueue.put("3");
            21. } catch (InterruptedException e) {
            22. e.printStackTrace();
            23. }
            24. },"T1").start();
            25. new Thread(()->{
            26. try {
            27. TimeUnit.SECONDS.sleep(3);
            28. System.out.println(Thread.currentThread().getName()+"="+blockingQueue.take());
            29. TimeUnit.SECONDS.sleep(3);
            30. System.out.println(Thread.currentThread().getName()+"="+blockingQueue.take());
            31. TimeUnit.SECONDS.sleep(3);
            32. System.out.println(Thread.currentThread().getName()+"="+blockingQueue.take());
            33. } catch (InterruptedException e) {
            34. e.printStackTrace();
            35. }
            36. },"T2").start();
            37. }
            38. }

          19. 相关阅读:
            【5G MAC】RA-RNTI的计算过程
            100天精通Golang(基础入门篇)——第20天:Golang 接口 深度解析☞从基础到高级
            Java HashMap常见面试题
            29.CF1149C [Tree Generator™](httpswww.luogu.com.cnproblemCF1149C) 区间合并线段树
            java-- 字符串+拼接详解, 性能调优 (底层原理实现)
            Spring IOC
            java解析c结构体的数据
            【太阳能多电平逆变器】采用SPWM技术的太阳能供电多电平逆变器研究(simulink)
            如何申请 Azure OpenAI
            统一网关Gateway快速入门
          20. 原文地址:https://blog.csdn.net/qq_53374893/article/details/132941604
            • 最新文章
            • 攻防演习之三天拿下官网站群
              数据安全治理学习——前期安全规划和安全管理体系建设
              企业安全 | 企业内一次钓鱼演练准备过程
              内网渗透测试 | Kerberos协议及其部分攻击手法
              0day的产生 | 不懂代码的"代码审计"
              安装scrcpy-client模块av模块异常,环境问题解决方案
              leetcode hot100【LeetCode 279. 完全平方数】java实现
              OpenWrt下安装Mosquitto
              AnatoMask论文汇总
              【AI日记】24.11.01 LangChain、openai api和github copilot
            • 热门文章
            • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
              奉劝各位学弟学妹们,该打造你的技术影响力了!
              五年了,我在 CSDN 的两个一百万。
              Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
              面试官都震惊,你这网络基础可以啊!
              你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
              心情不好的时候,用 Python 画棵樱花树送给自己吧
              通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
              13 万字 C 语言从入门到精通保姆级教程2021 年版
              10行代码集2000张美女图,Python爬虫120例,再上征途
            Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
            正则表达式工具 cron表达式工具 密码生成工具

            京公网安备 11010502049817号