<small id='Mq3Yr6Iy'></small> <noframes id='84HiPb2lTt'>

  • <tfoot id='j8LYZSMoV'></tfoot>

      <legend id='p4PjlDd56C'><style id='PeaK8bcGs'><dir id='WI8AD6wai'><q id='aLvhEU4'></q></dir></style></legend>
      <i id='24y1s'><tr id='ZqUtpBOr'><dt id='s10uT'><q id='t9esA6RVv'><span id='ZEW8FsC'><b id='Z6fu4N1n'><form id='SIvx'><ins id='VQXMlb9AKR'></ins><ul id='BiyfM0g'></ul><sub id='6mrQPAipe'></sub></form><legend id='SY0ymrjebV'></legend><bdo id='7Uh2'><pre id='8XrkQHWBL4'><center id='g0JPeaO'></center></pre></bdo></b><th id='JEznKL'></th></span></q></dt></tr></i><div id='F7j4dcYuy'><tfoot id='3nhC4xE'></tfoot><dl id='a712RjZ'><fieldset id='jt4yuIpm'></fieldset></dl></div>

          <bdo id='MWOgnN12'></bdo><ul id='qy25TMIcDY'></ul>

          1. <li id='oNGe7OCub3'></li>
            登陆

            彩票1号平台-“全栈2019”Java原子操作第九章:atomic包下原子数组介绍与运用

            admin 2019-05-14 188人围观 ,发现0个评论

            难度

            初级

            学习时刻

            30分钟

            合适人群

            零根底

            开发言语

            Java

            开发环境

            • JDK v11
            • IntelliJIDEA v2018.3

            友谊提示

            • 本教育归于系列教育,内容具有连贯性,本章运用到的内容之前教育中都有具体解说。
            • 本章内容针对零根底或根底较差的同学比较友爱,或许关于有根底的同学来说很简单,期望咱们能够依据自己的实际状况挑选继续看完或等候看下一篇文章。谢谢咱们的体谅!

            1.温故知新

            前面在《“全栈2019”Java原子操作第四章:AtomicBoolean介绍与运用》一章中介绍了什么是原子操作类AtomicBoolean

            《“全栈2019”Java原子操作第五章:AtomicInteger介绍与运用》一章中介绍了什么是原子操作类AtomicInteger

            《“全栈2019”Java原子操作第六章:AtomicInteger灵敏的运算办法》一章中介绍了运用原子操作类AtomicInteger的办法完成更灵敏的运算办法

            《“全栈2019”Java原子操作第七章:AtomicLong介绍与运用》一章中介绍了什么是原子操作类AtomicLong

            《“全栈2019”Java原子操作第八章:AtomicReference介绍与运用》一章中介绍了什么是原子操作类AtomicReference

            现在介绍原子数组AtomicIntegerArray、AtomicLongArray和AtomicReferenceArray

            2.什么是原子数组?

            望文生义,原子数组便是完成了原子操作的数组。

            原子操作的概念和必备常识在该系列的《“全栈2019”Java原子操作第一章:内存可见性volatile关键字解析》《“全栈2019”Java原子操作第二章:i++是原子操作吗?何为原子性》以及《“全栈2019”Java原子操作第三章:比较并沟通CAS技能详解》三章中现已具体介绍过了,这儿就不在赘述。不清楚的小伙伴请前去查阅相关章节。

            3.原子数组有哪些?

            java.util.concurrent.atomic包下一共有三个原子数组类:AtomicIntegerArray、AtomicLongArray和AtomicReferenceArray

            其间:

            AtomicIntegerArray是一个以原子办法操作int数组中的元素的类。

            AtomicLongArray是一个以原子办法操作long数组中的元素的类。

            AtomicReferenceArray是一个以原子办法操作目标数组中的元素的类。

            4.原子数组创立办法迥然不同

            AtomicIntegerArray的结构办法:

            • AtomicIntegerArray(int length)
            • AtomicIntegerArray(int[] array)

            AtomicLongArray的结构办法:

            • AtomicLongArray(int length)
            • AtomicLon彩票1号平台-“全栈2019”Java原子操作第九章:atomic包下原子数组介绍与运用gArray(long[] array)

            AtomicReferenceArray的结构办法:

            • AtomicReferenceArray(int length)
            • AtomicReferenceArray(E[] array)

            能够看到的是三个原子数组的结构办法除了类名不同以外,第一个结构办法都是指定数组初始长度;第二个结构办法都是能够指定相应类型自定义数组。

            5.为什么需求原子数组?

            假如没有原子数组的话,在多线程操作数组元素的状况下,会呈现并发问题。

            就以三个原子数组中的AtomicIntegerArray来举例说明,咱们能够先来看一个能够来看一个一般int数组操作元素时的场景。

            首要,创立一个长度为10的int数组:

            int数组一旦被创立出来,那么数组里边的元素初始值就为0。

            接着,创立一个操作元素的使命:

            然后,在run()办法里边对数组下标为0的元素进行自增:

            run()办法书写结束。

            接下来,咱们循环创立10个线程去履行操作元素的使命:

            最终,获取数组下标为0的元素:

            不过,推迟1秒钟再进行获取:

            比方书写结束。

            运转程序,履行成果:

            从运转成果来看,契合预期。

            数组下标为0的元素被自增了10次,成果为10,正确。

            可是咱们只需对程序稍加改动,成果就有所不同。

            下面,咱们改写比方。

            在操作元素的使命中,每次自增元素之前使当时线程睡100毫秒:

            比方改写结束。

            运转程序,履行成果:

            从运转成果来看,契合预期。

            程序稍加改动之后,咱们操作元素的成果就和之前的不同,这便是多线程操作同一数组元素发生的问题。

            怎样处理呢?

            咱们只需对数组内的元素进行原子办法操作的话即可。

            有什么办法能够完成对数组元素原子操作呢?

            关于int数组而言,运用AtomicIntegerArray即可。

            下面,咱们就运用AtomicIntegerArray代替int数组:

            已然咱们用AtomicIntegerArray代替了int数组,那么数组内元素自增的写法也有所不同:

            其间,getAndIncrement(int i)办法是对指定下标的元素进行自增操作,该操作是原子的。

            当然了,咱们获取AtomicIntegerArray里边的元素办法也有说改动:

            其间,get(int i)办法是获取指定下标的元素。

            比方改写结束。

            运转程序,履行成果:

            从运转成果来看,契合预期。

            由于AtomicIntegerArray是以原子办法操作元素的办法,所以即便在多线程的状况下也不会数据不一致发生问题。

            以上便是一般int数组和AtomicIntegerArray的差异。

            接下来,看看三个原子数组中的常用办法,它们大多数是相同的,仅仅参数类型不同罢了。

            6.AtomicIntegerArray常用办法

            • get(int i)办法的作用是获取指定下标元素;
            • set(int i, int newValue)办法的作用是设置指定下标元素的值。参数i是下标,newValue是咱们能够指定的新值。
            • getAndIncrement(int i)办法的作用是递加指定下标元素的值,回来递加前的值。
            • incrementAndGet(int i)办法的作用是递加指定下标元素的值,回来递加后的值。
            • getAndDecrement(int i)办法的作用是递减指定下标元素的值,回来递减前的值。
            • decrementAndGet(int i)办法的作用是递减指定下标元素的值,回来递减后的值。
            • getAndAdd(int i, int delta)办法的作用是指定下标元素与delta相加,回来相加前的值。
            • addAndGet(int i, int delta)办法的作用是指定下标元素与delta相加,回来相加后的值。
            • getAndUpdate(int i, IntUnaryOperator updateFunction)办法的作用是更新指定下标元素,更新办法由参数updateFunction决议,办法回来更新前的值。
            • updateAndGet(int i, IntUnaryOperator updateFunction)办法的作用是更新指定下标元素,更新办法由参数updateFunction决议,办法回来更新后的值。
            • getAndAccumulate(int i, int x, IntBinaryOperator accumulatorFunction)办法的作用是指定下标元素与参数x进行二元运算,运算办法由参数accumulatorFunction决议,办法回来运算前的值。
            • getAndAccumulate(int i, int x, IntBinaryOperator accumulatorFunction)办法的作用是指定下标元素与参数x进行二元运算,运算办法由参数accumulatorFunction决议,办法回来运算后的值。
            • compareAndSet(int i, int expectedValue, int newValue)办法的作用是假如当value==expectedValue,那么就将newValue赋给value,不然什么也不做。

            7.AtomicLongArray常用办法

            • get(int i)办法的作用是获取指定下标元素;
            • set(int i, long newValue)办法的作用是设置指定下标元素的值。参数i是下标,newValue是咱们能够指定的新值。
            • getAndIncrement(int i)办法的作用是递加指定下标元素的值,回来递加前的值。
            • incrementAndGet(int i)办法的作用是递加指定下标元素的值,回来递加后的值。
            • getAndDecrement(int i)办法的作用是递减指定下标元素的值,回来递减前的值。
            • decrementAndGet(int i)办法的作用是递减指定下标元素的值,回来递减后的值。
            • getAndAdd(int i, long delta)办法的作用是指定下标元素与delta相加,回来相加前的值。
            • addAndGet(int i, long delta)办法的作用是指定下标元素与delta相加,回来相加后的值。
            • getAndUpdate(int i, LongUnaryOperator updateFunction)办法的作用是更新指定下标元素,更新办法由参数updateFunction决议,办法回来更新前的值。
            • updateAndGet(int i, LongUnaryOperator updateFunction)办法的作用是更新指定下标元素,更新办法由参数updateFunction决议,办法回来更新后的值。
            • getAndAccumulate(int i, long x, LongBinaryOperator accumulatorFunction)办法的作用是指定下标元素与参数x进行二元运算,运算办法由参数accumulatorFunction决议,办法回来运算前的值。
            • accumulateAndGet(int i, long x, LongBinaryOperator accumulatorFunction)办法的作用是指定下标元素与参数x进行二元运算,运算办法由参数accumulatorFunction决议,办法回来运算后的值。
            • compareAndSet(int i, long expectedValue, int newValue)办法的作用是假如当value==expectedValue,那么就将newValue赋给value,不然什么也不做。

            8.AtomicReferenceArray常用办法

            • get(int i)办法的作用是获取指定下标元素;
            • set(int i, E newValue)办法的作用是设置指定下标元素的值。参数i是下标,newValue是咱们能够指定的新值。
            • getAndUpdate(int i, UnaryOperator updateFunction)办法的作用是更新指定下标元素,更新办法由参数updateFunction决议,办法回来更新前的值。
            • updateAndGet(int i, UnaryOperator updateFunction)办法的作用是更新指定下标元素,更新办法由参数updateFunction决议,办法回来更新后的值。
            • getAndAccumulate(int i, E x, BinaryOperator accumulatorFunction)办法的作用是指定下标元素与参数x进行二元运算,运算办法由参数accumulatorFunction决议,办法回来运算前的值。
            • accumulateAndGet(int i, E x, BinaryOperator accumulatorFunction)办法的作用是指定下标元素与参数x进行二元运算,运算办法由参数accumulatorFunction决议,办法回来运算后的值。
            • compareAndSet(int i, E expectedValue, E newValue)办法的作用是假如当value==expectedValue,那么就将newValue赋给value,不然什么也不做。

            接下来是办法示例。

            留意:三个原子数组的办法用法相同仅仅参数类型不同,所以这儿选取AtomicIntegerArray目标进行办法演示。

            9.获取指定下标元素get(int i)办法

            get(int i)办法的作用是获取AtomicIntegerArray目标中指定下标元素;

            例如,咱们创立一个AtomicIntegerArray目标:

            然后,调用其get(int i)办法获取元素:

            比方书写结束。

            运转程序,履行成果:

            从运转成果来看,契合预期。

            获取完元素之后,怎样设置指定下标元素的值呢?

            10.设置指定下标元素的值set(int i, int newValue)办法

            set(int i, int newValue)办法的作用是设置指定下标元素的值。参数i是下标,newValue是咱们能够指定的新值。

            例如,咱们创立一个AtomicIntegerArray目标:

            然后,调用其set(int i, int newValue)办法将下标为0的元素的值设置为99:

            接着,调用其get(int i)办法获取下标为0的元素:

            比方书写结束。

            运转程序,履行成果:

            从运转成果来看,契合预期。

            设置完元素之后,怎样指定下标元素自增呢?

            11.指定下标元素递加办法

            AtomicIntegerArray类中有两个递加办法:

            • getAndIncrement(int i)
            • incrementAndGet(int i)

            其间,getAndIncrement(int i)办法相当于i++,incrementAndGet(int i)办法相当于++i。

            getAndIncrement(int i)办法的作用是回来递加前的值。

            incrementAndGet(int i)办法的作用是回来递加后的值。

            例如,咱们创立一个AtomicIntegerArray目标:

            先调用getAndIncrement(int i)办法使下标为0的元素递加一次并输出成果:

            接着,调用incrementAndGet(int i)办法再使下标为0的元素递加一次并输出成果:

            比方书写结束。

            运转程序,履行成果:

            从运转成果来看,契合预期。

            下标为0的元素初始值为0,getAndIncrement(int i)办法回来递加前的值,也便是0,然后递加之后下标为0的元素的值变为1,接着调用incrementAndGet(int i)办法使其在1的根底上再递加一次变为2,成果为正确。

            指定下标元素递加之后,怎样指定下标元素递减呢?

            12.指定下标元素递减办法

            AtomicIntegerArray类中有两个递减办法:

            • getAndDecrement(int i)
            • decrementAndGet(int i)

            其间,getAndDecrement(int i)办法相当于i--,decrementAndGet(int i)办法相当于--i。

            getAndDecrement(int i)办法的作用是回来递减前的值。

            decrementAndGet(int i)办法的作用是回来递减后的值。

            例如,咱们创立一个AtomicIntegerArray目标:

            先调用getAndDecrement(int i)办法使下标为0的元素递减一次并输出成果:

            接着,调用decrementAndGet(int i)办法再使下标为0的元素递减一次并输出成果:

            比方书写结束。

            运转程序,履行成果:

            从运转成果来看,契合预期。

            下标为0的元素初始值为0,getAndDecrement(int i)办法回来递减前的值,也便是0,然后递减之后下标为0的元素的值变为-1,接着调用decrementAndGet(int i)办法使其在-1的根底上再递减一次变为-2,成果为正确。

            指定下标元素递减之后,怎样指定下标元素与恣意值相加呢?

            13.指定下标元素与恣意值相加办法

            前面两末节演示的是递加和递减状况,假如想要指定下标元素加上恣意数,比方+5,或许你想要减去恣意数,比方-5,运用前面那几个办法是做不到的,所以AtomicIntegerArray类也为咱们供给相应办法。

            AtomicIntegerArray类中有两个指定下标元素与恣意值相加办法:

            • getAndAdd(int i, int delta)
            • addAndGet(int i, int delta)

            其间:

            getAndAdd(int i, int delta)办法的作用是回来相加前的值。

            addAndGet(int i, int delta)办法的作用是回来相加后的值。

            例如,咱们创立一个AtomicIntegerArray目标:

            先调用getAndAdd(int i, int delta)办法使下标为0的元素与2相加并输出成果:

            接着,调用addAndGet(int i, int delta)办法再使下标为0的元素与-3相加并输出成果:

            比方书写结束。

            运转程序,履行成果:

            从运转成果来看,契合预期。

            下标为0的元素初始值为0,getAndAdd(int i, int delta)办法回来相加前的值,也便是0,然后相加之后下标为0的元素的值变为2,接着调用addAndGet(int i, int delta)办法使其在2的根底上再相加一次-3变为-1,成果为正确。

            在了解指定下标元素与恣意值相加之后,我想运用自定义办法更新指定下标元素该怎样做呢?

            14.运用自定义办法更新指定下标元素

            前面几个末节演示的都是和指定数的加法或减法,假如我想自定义更新指定下标元素的值怎样做呢?

            为此,AtomicIntegerArray类供给了两个运用自定义办法更新指定下标元素的值的办法:

            • getAndUpdate(int i, IntUnaryOperator updateFunction)
            • updateAndGet(int i, IntUnaryOperator updateFunction)

            其间:

            getAndUpdate(int i, IntUnaryOperator updateFunction)办法的作用是回来更新前的值。

            updateAndGet(int i, IntUnaryOperator updateFunction)办法的作用是回来更新后的值。

            getAndUpdate(int i, IntUnaryOperator updateFunction)办法和updateAndGet(int i, IntUnaryOperator updateFunction)办法都需求一个IntUnaryOperator类型的参数,而IntUnaryOperator是一个接口:

            咱们只需完成IntUnaryOperator接口中的applyAsInt(int operand)办法即可:

            applyAsInt(int operand)办法是写怎么更新元素的当地。

            下面,咱们就来试试getAndUpdate(int i, IntUnaryOperator updateFunction)办法和updateAndGet(int i, IntUnaryOperator updateFunction)办法。

            首要,咱们创立一个AtomicIntegerArray目标:

            先调用getAndUpdate(int i, IntUnaryOperator updateFunction)办法使下标为0的元素与5相加并输出成果:

            接着,调用u彩票1号平台-“全栈2019”Java原子操作第九章:atomic包下原子数组介绍与运用pdateAndGet(int i, IntUnaryOperator updateFunction)办法再使下标为0的元素与2相乘并输出成果:

            比方书写结束。

            运转程序,履行成果:

            从运转成果来看,契合预期。

            下标为0的元素初始值为0,getAndUpdate(int i, IntUnaryOperator updateFunction)办法回来递减前的值,也便是0,然后下标为0的元素与5相加变为5,接着调用updateAndGet(int i, IntUnaryOperator updateFunction)办法使其在5的根底上再乘以2变为10,成果为正确。

            在了解运用自定义办法更新指定下标元素之后,我想指定下标元素与指定值进行二元运算该怎样做呢?

            15.指定下标元素与指定值进行二元运算

            假如咱们想指定下标元素与指定值进行二元运算该怎样做呢?

            为此,AtomicIntegerArray类供给了两个指定下标元素与指定值进行二元运算的办法:

            • getAndAccumulate(int i, int x, IntBinaryOperator accumulatorFunction)
            • accumulateAndGet(int i, int x, IntBinaryOperator accumulatorFunction)

            其间:

            getAndAccumulate(int i, int x, IntBinaryOperator accumulatorFunction)办法的作用是回来运算前的值。

            accumulateAndGet(int i, int x, IntBinaryOperator accumulatorFunction)办法的作用是回来运算后的值。

            参数解说

            int i:指定参加运算的下标元素,即left值(结合IntBinaryOperator即可来看)。

            int x:指定参加运算的值,即right值(结合IntBinaryOperator接口来看)。

            IntBinaryOperator accumulatorFunction二元运算的办法。

            其间,IntBinaryOperator是一个接口:

            咱们只需完成IntBinaryOperator接口中的applyAsInt(int left, int right)办法即可:

            applyAsInt(int left, int right)办法是写怎么将两个元素进行二元运算的当地。

            示例

            首要,咱们创立一个AtomicIntegerArray目标:

            先调用getAndAccumulate(int i, int x, IntBinaryOperator accumulatorFunction)办法使下标为0的元素与4相加并输出成果:

            接着,调用accumulateAndGet(int i, int x, IntBinaryOperator accumulatorFunction)办法再使下标为0的元素与5相乘并输出成果:

            比方书写throw结束。

            运转程序,履行成果:

            从运转成果来看,契合预期。

            下标为0的元素初始值为0,先调用getAndAccumulate(int i, int x, IntBinaryOperator accumulatorFunction)办法回来递减前的值,也便是0,然后下标为0的元素与4相加变为4,接着调用accumulateAndGet(int i, int x, IntBinaryOperator accumulatorFunction)办法使其在4的根底上再乘以5变为20,成果为正确。

            在了解指定下标元素与指定值进行二元运算之后,我想知道AtomicIntegerArray有表现CAS算法吗?

            16.CAS算法表现

            咱们之前在《“全栈2019”Java原子操作第三章:比较并沟通CAS技能详解》一章中学习过什么是CAS算法。

            在AtomicIntegerArray类中也有表现:

            compareAndSet(int i, int expectedValue, int newValue)办法的作用是假如当value==expectedValue,那么就将newValue赋给value,不然什么也不做。

            参数解说

            int i:操作指定的下标元素。

            int expectedValue:预期值。

            int newValue:新值。

            示例

            首要,咱们创立一个AtomicIntegerArray目标并指定初始值,初始值为0:

            然后,在调用compareAndSet(int i, int expectedValue, int newValue)办法之前获取一次下标为0的元素:

            接着,调用compareAndSet(int i, int expectedValue, int newValue)办法并输出办法回来成果:

            最终,咱们再获取一次下标为0的元素:

            比方改写结束。

            运转程序,履行成果:

            从运转成果来看,契合预期。

            当然了,你也能够将预期值改为一个非原值的数,这样赋值就不成功。

            最终,期望咱们能够把这个比方照着写一遍,然后再自己默写一遍,便利今后碰到相似的面试题能够轻松应对。

            祝咱们编码愉快!

            GitHub

            本章程序GitHub地址:https://github.com/gorhaf/Java2019/tree/master/Thread/atomic/AtomicIntegerArray

            总结

            • AtomicIntegerArray是一个以原子办法操作int数组中的元素的类。
            • AtomicLongArray是一个以原子办法操作long数组中的元素的类。
            • AtomicReferenceArray是一个以原子办法操作目标数组中的元素的类。
            • get(int i)办法的作用是获取指定下标元素;
            • set(int i, int newValue)/set(int i, long newValue)/set(int i, E newValue)办法的作用是设置指定下标元素的值。参数i是下标,newValue是咱们能够指定的新值。
            • getAndIncrement(int i)办法的作用是递加指定下标元素的值,回来递加前的值。【注:AtomicReferenceArray无此办法】
            • incrementAndGet(int i)办法的作用是递加指定下标元素的值,回来递加后的值。【注:AtomicReferenceArray无此办法】
            • getAndDecrement(int i)办法的作用是递减指定下标元素的值,回来递减前的值。【注:AtomicReferenceArray无此办法】
            • decrementAndGet(int i)办法的作用是递减指定下标元素的值,回来递减后的值。【注:AtomicReferenceArray无此办法】
            • getAndAdd(int i, int delta)/getAndAdd(int i, long delta)办法的作用是指定下标元素与delta相加,回来相加前的值。【注:AtomicReferenceArray无此办法】
            • addAndGet(int i, int delta)/addAndGet(int i, long delta)办法的作用是指定下标元素与delta相加,回来相加后的值。【注:AtomicReferenceArray无此办法】
            • getAndUpdate(int i, IntUnaryOperator updateFunction)/getAndUpdate(int i, LongUnaryOperator updateFunction)/getAndUpdate(int i, UnaryOperator updateFunction)办法的作用是更新指定下标元素,更新办法由参数updateFunction决议,办法回来更新前的值。
            • updateAndGet(int i, IntUnaryOperator updateFunction)/updateAndGet(int i, LongUnaryOperator updateFunction)/updateAndGet(int i, UnaryOperator updateFunction)办法的作用是更新指定下标元素,更新办法由参数updateFunction决议,办法回来更新后的值。
            • getAndAccumulate(int i, int x, IntBinaryOperator accumulatorFunction)/getAndAccumulate(int i, long x, LongBinaryOperator accumulatorFunction)/getAndAccumulate(int i, E x, BinaryOperator accumulatorFunction)办法的作用是指定下标元素与参数x进行二元运算,运算办法由参数accumulatorFunction决议,办法回来运算前的值。
            • getAndAccumulate(int i, int x, IntBinaryOperator accumulatorFunction)/accumulateAndGet(int i, long x, LongBinaryOperator accumulatorFunction)/accumulateAndGet(int i, E x, BinaryOperato彩票1号平台-“全栈2019”Java原子操作第九章:atomic包下原子数组介绍与运用r accumulatorFunction)办法的作用是指定下标元素与参数x进行二元运算,运算办法由参数accumulatorFunction决议,办法回来运算后的值。
            • compareAndSet(int i, int expectedValue, int newValue)/compareAndSet(int i, long expectedValue, int newValue)/compareAndSet(int i, E expectedValue, E newValue)办法的作用是假如当value==expectedValue,那么就将newValue赋给value,不然什么也不做。

            至此,Java华夏子数组AtomicIntegerArray、AtomicLongArray和AtomicReferenceArray相关内容解说先告一段落,更多内容请继续重视。

            答疑

            假如咱们有问题或想了解更多前沿技能,请在下方留言或谈论,我会为咱们回答。

            上一章

            “全栈2019”Java原子操作第八章:AtomicReference介绍与运用

            下一章

            “全栈2019”Java原子操作第十章:atomic包下原子更新器介绍

            学习小组

            参加同步学习小组,一起沟通与前进。

            • 办法一:重视头条号Gorhaf,私信“Java学习小组”。
            • 办法二:重视大众号Gorhaf,回复“Java学习小组”。

            全栈工程师学习方案

            重视咱们,参加“全栈工程师学习方案”。

            版权声明

            原创不易,未经答应不得转载!

            请关注微信公众号
            微信二维码
            不容错过
            Powered By Z-BlogPHP