返回顶部
首页 > 资讯 > 精选 >如何使用Java中无锁技术
  • 692
分享到

如何使用Java中无锁技术

2023-06-16 09:06:03 692人浏览 八月长安
摘要

本篇内容介绍了“如何使用Java中无锁技术”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、原子工具类jdk 1.8 中,java.util

本篇内容介绍了“如何使用Java中无技术”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

一、原子工具类

jdk 1.8 中,java.util.concurrent.atomic 包下类都是原子类,原子类都是基于 sun.misc.Unsafe  实现的。

  • CPU 为了解决并发问题,提供了 CAS 指令,全称 Compare And Swap,即比较并交互

  • CAS 指令需要 3 个参数,变量、比较值、新值。当变量的当前值与比较值相等时,才把变量更新为新值

  • CAS 是一条 CPU 指令,由 CPU 硬件级别上保证原子性

java.util.concurrent.atomic  包中的原子分为:原子性基本数据类型、原子性对象引用类型、原子性数组、原子性对象属性更新器和原子性累加器

原子性基本数据类型:AtomicBoolean、AtomicInteger、AtomicLong

原子性对象引用类型:AtomicReference、AtomicStampedReference、AtomicMarkableReference

原子性数组:AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray

原子性对象属性更新:AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicReferenceFieldUpdater

原子性累加器:DoubleAccumulator、DoubleAdder、LongAccumulator、LongAdder

修改我们之前测试原子性问题的类,使用 AtomicInteger 的简单例子

package constxiong.concurrency.a026;  import java.util.concurrent.atomic.AtomicInteger;   public class TestAtomicInteger {   // 计数变量  static volatile AtomicInteger count = new AtomicInteger(0);   public static void main(String[] args) throws InterruptedException {  // 线程 1 给 count 加 10000  Thread t1 = new Thread(() -> {  for (int j = 0; j <10000; j++) {  count.incrementAndGet();  }  System.out.println("thread t1 count 加 10000 结束");  });   // 线程 2 给 count 加 10000  Thread t2 = new Thread(() -> {  for (int j = 0; j <10000; j++) {  count.incrementAndGet();  }  System.out.println("thread t2 count 加 10000 结束");  });   // 启动线程 1  t1.start();  // 启动线程 2  t2.start();   // 等待线程 1 执行完成  t1.join();  // 等待线程 2 执行完成  t2.join();   // 打印 count 变量  System.out.println(count.get());  }  }

打印结果如预期

thread t2 count 加 10000 结束 thread t1 count 加 10000 结束 20000

二、线程本地存储

  • java.lang.ThreadLocal 类用于线程本地化存储。

  • 线程本地化存储,就是为每一个线程创建一个变量,只有本线程可以在该变量中查看和修改值。

  • 典型的使用例子就是,spring 在处理数据库事务问题的时候,就用了 ThreadLocal 为每个线程存储了各自的数据库连接  Connection。

  • 使用 ThreadLocal 要注意,在不使用该变量的时候,一定要调用 remove() 方法移除变量,否则可能造成内存泄漏的问题。

示例

package constxiong.concurrency.a026;   public class TestThreadLocal {   // 线程本地存储变量  private static final ThreadLocal<Integer> THREAD_LOCAL_NUM = new ThreadLocal<Integer>() {  @Override  protected Integer initialValue() {//初始值  return 0;  }  };   public static void main(String[] args) {  for (int i = 0; i <3; i++) {// 启动三个线程  Thread t = new Thread() {  @Override  public void run() {  add10ByThreadLocal();  }  };  t.start();  }  }     private static void add10ByThreadLocal() {  try {  for (int i = 0; i <5; i++) {  Integer n = THREAD_LOCAL_NUM.get();  n += 1;  THREAD_LOCAL_NUM.set(n);  System.out.println(Thread.currentThread().getName() + " : ThreadLocal num=" + n);  }  } finally {  THREAD_LOCAL_NUM.remove();// 将变量移除  }  } }

每个线程最后一个值都打印到了 5

Thread-0 : ThreadLocal num=1 Thread-2 : ThreadLocal num=1 Thread-1 : ThreadLocal num=1 Thread-2 : ThreadLocal num=2 Thread-0 : ThreadLocal num=2 Thread-2 : ThreadLocal num=3 Thread-0 : ThreadLocal num=3 Thread-1 : ThreadLocal num=2 Thread-0 : ThreadLocal num=4 Thread-2 : ThreadLocal num=4 Thread-0 : ThreadLocal num=5 Thread-1 : ThreadLocal num=3 Thread-2 : ThreadLocal num=5 Thread-1 : ThreadLocal num=4 Thread-1 : ThreadLocal num=5

三、copy-on-write

根据英文名称可以看出,需要写时复制,体现的是一种延时策略。

Java 中的 copy-on-write 容器包括:CopyOnWriteArrayList、CopyOnWriteArraySet。

涉及到数组的全量复制,所以也比较耗内存,在写少的情况下使用比较适合。

简单的 CopyOnWriteArrayList 的示例,这里只是说明 CopyOnWriteArrayList  怎么用,并且是线程安全的。这个场景并不适合使用 CopyOnWriteArrayList,因为写多读少。

package constxiong.concurrency.a026;  import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.CopyOnWriteArrayList;   public class TestCopyOnWrite {   private static final Random R = new Random();    private static CopyOnWriteArrayList<Integer> cowList = new CopyOnWriteArrayList<Integer>(); // private static ArrayList<Integer> cowList = new ArrayList<Integer>();    public static void main(String[] args) throws InterruptedException {  List<Thread> threadList = new ArrayList<Thread>();  //启动 1000 个线程,向 cowList 添加 5 个随机整数  for (int i = 0; i <1000; i++) {  Thread t = new Thread(() -> {  for (int j = 0; j <5; j++) {  //休眠 10 毫秒,让线程同时向 cowList 添加整数,引出并发问题  try {  Thread.sleep(10);  } catch (InterruptedException e) {  e.printStackTrace();  }  cowList.add(R.nextInt(100));  }  }) ;  t.start();  threadList.add(t);  }    for (Thread t : threadList) {  t.join();  }  System.out.println(cowList.size());  } }

打印结果

5000

如果把

private static CopyOnWriteArrayList<Integer> cowList = new CopyOnWriteArrayList<Integer>();

改为

private static ArrayList<Integer> cowList = new ArrayList<Integer>();

打印结果就是小于 5000 的整数了

“如何使用Java中无锁技术”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: 如何使用Java中无锁技术

本文链接: https://lsjlt.com/news/283145.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 如何使用Java中无锁技术
    本篇内容介绍了“如何使用Java中无锁技术”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、原子工具类JDK 1.8 中,java.util...
    99+
    2023-06-16
  • Java中如何使用重定向技术?
    重定向技术是指在Java中将输出流重定向到另一个目标的技术。在Java中,标准输出流(System.out)和标准错误流(System.err)都可以被重定向到其他目标。本文将介绍Java中如何使用重定向技术,并提供相关的演示代码。 一、...
    99+
    2023-06-26
    重定向 javascript 教程
  • Java开发中如何使用二维码技术?
    随着移动互联网的发展,二维码已经成为了一种非常流行的信息传递方式。在Java开发中,我们也可以使用二维码技术来实现一些功能。本文将介绍在Java开发中如何使用二维码技术,并提供相关的代码示例。 一、什么是二维码? 二维码是一种矩阵式的条形...
    99+
    2023-09-18
    二维码 开发技术 对象
  • PHP中如何使用MongoDB技术?
    PHP中如何使用MongoDB技术?MongoDB是当今市场上流行的一种非关系型数据库。它以其良好的可扩展性、高性能、灵活的文档模型和强大的查询语言而受到越来越多的PHP开发者的青睐。本文将探讨在PHP项目中如何使用MongoDB技术。一、...
    99+
    2023-05-14
    技术 PHP MongoDB
  • Oracle中Flashback技术如何使用
    Oracle中的Flashback技术是一种用于恢复数据库到先前状态的功能。它可以帮助用户在不影响其他操作的情况下快速恢复误删除的数...
    99+
    2024-04-19
    Oracle
  • 如何使用Java赫夫曼树技术
    本篇内容介绍了“如何使用Java赫夫曼树技术”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!基本介绍给定 n 个权值作为 n 个叶子节点,构造...
    99+
    2023-06-15
  • 如何在Java文件中使用二维码技术?
    二维码技术是一种快速传输信息的方式,它已经在各行各业得到了广泛的应用。Java作为一种流行的编程语言,也提供了很多二维码技术的库和API供开发者使用。本文将介绍如何在Java文件中使用二维码技术。 一、使用zxing库生成二维码 zxing...
    99+
    2023-08-17
    文件 开发技术 二维码
  • 如何在Java中应用反射技术
    如何在Java中应用反射技术?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、反射概念Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象...
    99+
    2023-06-15
  • 在PHP中如何使用Memcached技术?
    Memcached是一种分布式内存缓存技术,被广泛应用于Web应用程序中。它可以帮助Web应用程序提高性能,减少数据库负载,加速数据访问,从而提高用户体验。在PHP中,使用Memcached技术也变得越来越流行。本文将介绍在PHP中如何使用...
    99+
    2023-05-14
    PHP memcached 技术使用
  • Java BasePooledObjectFactory对象池化技术如何使用
    本篇内容主要讲解“Java BasePooledObjectFactory对象池化技术如何使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java BasePooledOb...
    99+
    2023-07-05
  • 如何在Java中使用自然语言处理技术?
    Java作为一种流行的编程语言,在自然语言处理方面也有着广泛的应用。自然语言处理(NLP)是一种人工智能技术,它涉及计算机处理人类语言的能力。在本文中,我们将介绍如何在Java中使用自然语言处理技术。 安装自然语言处理库 Java有许多...
    99+
    2023-08-07
    自然语言处理 linux javascript
  • java中间件技术怎么使用
    Java中间件技术是一种用于帮助开发人员构建分布式应用程序的工具。它们提供了一系列功能和工具,用于处理分布式系统中的通信、事务、负载...
    99+
    2023-10-25
    java
  • 如何在 Java 开发中使用 UNIX 日志记录技术?
    在 Java 开发中,日志记录是非常重要的,它可以帮助开发人员快速地了解应用程序的运行情况,发现潜在的问题,从而及时进行修复。UNIX 日志记录技术是一种非常实用的工具,它可以帮助开发人员更好地管理和分析日志,提高应用程序的性能和可靠性。本...
    99+
    2023-11-15
    日志 unix 开发技术
  • 如何在Java项目中使用二维码扫描技术?
    当今数字化的时代,二维码扫描技术已经变得非常普及。无论是商业还是个人领域,都可以看到二维码的身影。那么,在Java项目中如何使用二维码扫描技术呢?本文将为您详细介绍。 一、二维码简介 二维码是一种由黑白相间的方块组成的矩阵条码,它可以将信息...
    99+
    2023-11-07
    npm 文件 二维码
  • 如何使用CMS+PDF技术
    本篇内容介绍了“如何使用CMS+PDF技术”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前端市场中的PDF...
    99+
    2024-04-02
  • 如何在自然语言处理中使用Java缓存技术和Shell命令行技术?
    自然语言处理(NLP)是人工智能领域中的一个重要分支。在处理大量的自然语言数据时,往往需要使用一些高效的技术来提高处理速度和效率。本文将介绍如何在自然语言处理中使用Java缓存技术和Shell命令行技术。 一、Java缓存技术 Java缓存...
    99+
    2023-06-30
    缓存 自然语言处理 shell
  • 如何在Java容器中使用自然语言处理技术?
    在当今的信息时代,自然语言处理技术(NLP)越来越受到关注。它不仅可以提高信息处理的效率,还可以让计算机更加智能化,更加人性化。在Java容器中,我们可以利用现有的NLP库来实现文本处理,从而实现更加智能化的应用。本文将介绍如何在Java容...
    99+
    2023-11-03
    开发技术 自然语言处理 容器
  • Java Swagger技术使用指南
    目录Swagger的作用与概念在项目中使用swagger配置swaggerApiInfo 配置swagger配置扫描接口配置api文档分组多个分组实体类配置Swagger的作用与概念...
    99+
    2024-04-02
  • Java多线程中Lock锁如何使用
    这篇文章主要介绍“Java多线程中Lock锁如何使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java多线程中Lock锁如何使用”文章能帮助大家解决问题。Lock基本使用Lock它是java.u...
    99+
    2023-07-02
  • java如何使用redis加锁
    目录java使用redis加锁redis锁用法java代码总结java使用redis加锁 1.编写LockUtil工具类 import org.springframework.bea...
    99+
    2023-01-09
    java使用redis加锁 java redis加锁 redis加锁
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作