iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Java并发编程ThreadLocalRandom类怎么使用
  • 788
分享到

Java并发编程ThreadLocalRandom类怎么使用

2023-07-02 08:07:12 788人浏览 独家记忆
摘要

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

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

为什么需要ThreadLocalRandom

java.util.Random一直都是使用比较广泛的随机数生成工具类,而且java.lang.Math中的随机数生成也是使用的java.util.Random实例。

我们下面看一下java.util.Random的使用方法:

import java.util.Random;public class code_4_threadRandom {    public static void main(String[] args) {        Random random = new Random();        for(int i = 0; i < 10; i++) {            System.out.println(                    random.nextInt(5)            );        }    }}

随机数的生成需要一个默认的种子,这个种子是一个long类型的数字,这可以通过创建Random对象时通过构造函数指定,如果不指定则在默认构造函数内部生成一个默认值。

public int nextInt(int bound) {//参数检查    if (bound <= 0)        throw new IllegalArgumentException(BadBound);//根据老的种子生成新的种子    int r = next(31);    int m = bound - 1;    if ((bound & m) == 0)  // i.e., bound is a power of 2    //根据新种子生成新的随机数        r = (int)((bound * (long)r) >> 31);    else {        for (int u = r;             u - (r = u % bound) + m < 0;             u = next(31);    }    return r;}

由上面代码可见,一个新的随机数生成需要两个步骤:首先根据老的种子生成新的种子,然后根据新的种子来计算新的随机数。如果在单线程的情况下每次调用nextInt都是根据老的种子计算出新的种子。但是在多线程下多个线程都可能都拿到同一个老的种子去生成新种子,这回导致多个线程生成的新随机数是相同的。我们需要当多个线程通过同一个老种子计算新种子时,当第一个线程的新种子被计算出来后,第二个线程要丢弃掉老种子,用第一个线程计算出的新种子来计算自己的新种子。在Random类中,对象初始化时的种子就被保存到了种子原子变量里。

下面看一下next()的代码:

protected int next(int bits) {    long oldseed, nextseed;    AtomicLong seed = this.seed;    do {        oldseed = seed.get();        nextseed = (oldseed * multiplier + addend) & mask;    } while (!seed.compareAndSet(oldseed, nextseed));    return (int)(nextseed >>> (48 - bits));}

在上面代码中,通过CAS操作来更新种子,在多线程情况下,多个线程同时计算随机数来计算新的种子,多个线程会竞争同一个原子变量的更新操作,会造成大量线程进行自旋重试,降低并发性能。所以ThreadLocalRandom应运而生。

ThreadRandom原理详解

import java.util.Random;public class code_4_threadLocalRandom {    public static void main(String[] args) {        Random random = new ThreadLocalRandom.current();        for(int i = 0; i < 10; i++) {            System.out.println(                    random1.nextInt(5)            );        }    }}

如果每个线程都维护一个种子变量,则每个线程生成随机数时都根据自己老的种子计算新的种子,并使用新的种子更新老种子,再根据新种子计算随机数,这就不会存在竞争问题了。ThreadLocalRandom 类 继 承 了 Random 类 并 重 写 了 nextlnt方法,在 ThreadLocalRandom 类中并没有使用继承自Random 类的原子性种子变量。

在ThreadLocalRandom中并没有存放具体的种子,具体的种子存放在具体的调用线程的 threadLocalRandomSeed 变量里面。ThreadLocalRandom 类似于 ThreadLocal 类,就是个工具类。当线程调用 ThreadLocalRandom的current 方法时,ThreadLocalRandom 负责初始化调用线程的threadLocalRandomSeed 变量,也就是初始化种子。当 调 用 ThreadLocalRandom 的 nextInt 方 法 时, 实际 上 是 获 取 当前 线 程的threadLocalRandomSeed 变量作为当前种子来计算新的种子,然后更新新的种子到当前线程的threadLocalRandomSeed 变量,而后再根据新种子并使用具体算法计算随机数。这里需要注意的是,threadLocalRandomSeed 变量就是 Thread 类里面的一个普通 long 变量,它并不是原子性变量。其实道理很简单,因为这个变量是线程级别的,所以根本不需要使用原子性变量。

变量instance是ThreadLocalRandom的一个实例,该变量是static的。当多线程通过ThreadLocalRandom的current方法获取ThreadLocalRandom的实例时,其实是同一个实例。但是由于具体的种子是存放在线程里面的,所以在ThreadLocalRandom的实例里面只包含与线程无关的通用算法,所以它是线程安全的。

java并发编程ThreadLocalRandom类怎么使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: Java并发编程ThreadLocalRandom类怎么使用

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

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

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java并发编程ThreadLocalRandom类怎么使用
    本篇内容介绍了“Java并发编程ThreadLocalRandom类怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!为什么需要Thre...
    99+
    2023-07-02
  • Java并发编程ThreadLocalRandom类详解
    目录为什么需要ThreadLocalRandomThreadRandom原理详解为什么需要ThreadLocalRandom java.util.Random一直都是使用比较广泛的随...
    99+
    2024-04-02
  • C#并发编程之Task类怎么使用
    这篇文章主要介绍了C#并发编程之Task类怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C#并发编程之Task类怎么使用文章都会有所收获,下面我们一起来看看吧。Task.RunTask是建立在线程池之上...
    99+
    2023-07-05
  • Java并发编程之工具类Semaphore的使用
    一、Semaphore的理解 Semaphore属于java.util.concurrent包; Semaphore翻译成字面意思为信号量,Semaphore可以控...
    99+
    2024-04-02
  • Java并发编程之LinkedBlockingQueue队列怎么使用
    这篇文章主要介绍了Java并发编程之LinkedBlockingQueue队列怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java并发编程之LinkedBlockingQueue队列怎么使用文章都会有...
    99+
    2023-06-30
  • 怎么在Java中利用LockSupport类实现并发编程
    今天就跟大家聊聊有关怎么在Java中利用LockSupport类实现并发编程,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、LockSupport类的属性private ...
    99+
    2023-06-15
  • Java并发编程之LockSupport类详解
    目录一、LockSupport类的属性二、LockSupport类的构造函数三、park(Object blocker)方法 和 park()方法分析四、parkNanos(Obje...
    99+
    2024-04-02
  • Java并发编程之CountDownLatch的使用
    目录前言基本使用await尝试获取锁获取锁失败countDown方法前言 CountDownLatch是一个倒数的同步器,和其他同步器不同的是,state为0时表示获取锁成功。常用来...
    99+
    2023-05-20
    Java并发编程CountDownLatch Java CountDownLatch使用 Java CountDownLatch
  • 怎么在Java中使用CountDownLatch实现并发编程
    本篇文章为大家展示了怎么在Java中使用CountDownLatch实现并发编程,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Java是什么Java是一门面向对象编程语言,可以编写桌面应用程序、We...
    99+
    2023-06-14
  • Java并发编程之Executors类详解
    一、Executors的理解 Executors类属于java.util.concurrent包; 线程池的创建分为两种方式:ThreadPoolExecutor ...
    99+
    2024-04-02
  • 怎么在Java中使用ReentrantLock实现并发编程
    这篇文章给大家介绍怎么在Java中使用ReentrantLock实现并发编程,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、首先看图二、lock()跟踪源码这里对公平锁和非公平锁做了不同实现,由构造方法参数决定是否公...
    99+
    2023-06-15
  • Java并发编程之详解ConcurrentHashMap类
    前言 由于Java程序员常用的HashMap的操作方法不是同步的,所以在多线程环境下会导致存取操作数据不一致的问题,Map接口的另一个实现类Hashtable 虽然是线程安全的,但是...
    99+
    2024-04-02
  • Go并发编程sync.Cond怎么使用
    本篇内容主要讲解“Go并发编程sync.Cond怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Go并发编程sync.Cond怎么使用”吧!简介Go 标准库提供 Cond 原语的目的是,为...
    99+
    2023-06-30
  • 怎么用Java高并发编程之CountDownLatch
    本篇文章为大家展示了怎么用Java高并发编程之CountDownLatch,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。什么是CountDownLatchCountDownLatch是通过一个计数器...
    99+
    2023-06-15
  • java编程abstract类怎么使用
    在Java编程中,抽象类是一种特殊的类,它不能被实例化,只能被继承。抽象类通常用于定义一组相关的类的共同特性和行为。要使用抽象类,可...
    99+
    2023-08-15
    java abstract
  • java并发编程工具类JUC之ArrayBlockingQueue
    Java BlockingQueue接口java.util.concurrent.BlockingQueue表示一个可以存取元素,并且线程安全的队列。换句话说,当多线程同时从 Jav...
    99+
    2024-04-02
  • 详解Java并发编程之原子类
    目录原子数组AtomicIntegerArray原子更新器AtomicIntegerFieldUpdater原子累加器LongAdder原子数组 原子数组有AtomicInteger...
    99+
    2023-05-18
    Java并发原子类 Java并发
  • 如何使用Java高并发编程CyclicBarrier
    本篇内容介绍了“如何使用Java高并发编程CyclicBarrier”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!什么是CyclicBarr...
    99+
    2023-06-15
  • Java并发编程同步器CountDownLatch怎么用
    今天小编给大家分享一下Java并发编程同步器CountDownLatch怎么用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。...
    99+
    2023-06-30
  • Java并发编程之StampedLock锁怎么应用
    本篇内容介绍了“Java并发编程之StampedLock锁怎么应用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!StampedLock:St...
    99+
    2023-06-30
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作