精华内容
下载资源
问答
  • 原子结构是指原子构成组成以及部分的搭配和安排。原子是组成物质的微观粒子,今天小编就来带大家了解一下原子结构示意,深入了解一下原子。1、什么是原子结构示意图原子结构示意是表示原子核电荷数和电子层排...

    原子结构是指原子的构成组成以及部分的搭配和安排。原子是组成物质的微观粒子,今天小编就来带大家了解一下原子结构示意图,深入了解一下原子。

    1、什么是原子结构示意图

    原子结构示意图是表示原子核电荷数和电子层排布的图示形式。小圈和圈内的数字表示原子核和核内质子数,弧线表示电子层,弧线上的数字表示该层的电子数。

    2、原子结构示意图的原理

    1.核外电子是分层排列的,从里到外1,2,3,4,5,6,7。

    2.第一层最多2个电子,第二层最多8个电子,当电子层超过三层时,倒数第二层不超过18个电子;当电子层超过四层时,倒数第三层最多不超过32个电子,最外层不超过8个电子。

    3.最外层8个电子的结构叫做稳定结构(特殊的是稀有气体中的氦是最外层2个电子)。

    4.金属原子最外层电子数<4易失电子。

    5.每层最多排2×(n)^2个电子(n表示层数)

    6.非金属原子最外层电子数≥4 容易得到电子. 化学性质不稳定

    7.稀有气体最外层电子数是8个. He:(2个)不得不失(达到最稳定状态,所以稀有气体性质较稳定)。

    3、原子结构示意图的规律

    (1)各电子层最多容纳的电子数目是2n2。

    (2)其次,最外层电子数目不超过8个(K层为最外层时不超过2个)。

    (3)第三,次外层电子数目不超过18个,倒数第三层电子数目不超过32个。

    核外电子总是尽先排布在能量最低的电子层里,然后再由里往外依次排布在能量逐步升高的电子层里。

    4、原子结构示意图的常考点

    1.会根据最外层电子数初步判断原子的类型。最外层电子数小于4,一般属于金属原子;最外层电子数大于4,属于非金属原子;最外层电子数等于8,属于稀有气体原子,有一个特殊的稀有气体原子氦,它的最外层电子是2.注意:氢原子的最外层电子数是2,但属于非金属原子。

    2.会根据最外层电子数判断化学性质。最外层电子数相等,化学性质相似。

    3.会根据质子数和核外电子数判断阴阳离子和原子。质子数等于电子数,是原子;质子数大于电子数,是阳离子;质子数小于电子数,是阴离子。

    以上内容就是我们科学高分网所介绍的原子结构示意图的内容,同学们要学好这块知识,首先要学会如何去看图。

    展开全文
  • 该算法利用含噪图像通过字典学习算法得到自适应的冗余字典,然后提取字典中每个原子的HOG特征和灰度统计特征构成特征集,并利用原子的特征集将冗余字典中的原子分成两类(不含噪原子和噪声原子),最后利用不含噪...
  • 这是我们暑假课程的第7讲,所讲的内容是:①原子的结构;②构成物质的微粒之离子;③离子及离子结构。从开课以后,我们将会持续使用邵文老师的公众号来为同学们进行推送,进行暑假课堂的同步学习。(希望大家尽快熟悉...

         各位同学、各位家长,大家好,欢迎大家来到邵文老师的化学课堂,同时也欢迎大家来到“邵文老师带你说化”!这是我们暑假课程的第7讲,所讲的内容是:①原子的结构;②构成物质的微粒之离子;③离子及离子结构。从开课以后,我们将会持续使用邵文老师的公众号来为同学们进行推送,进行暑假课堂的同步学习。(希望大家尽快熟悉如何使用微信公众号里面的资料)

         在这一讲的内容里面,邵文老师为同学们比较详细的讲解了离子的概念、特征、种类、离子构成的物质以及原子与离子结构示意图,尤其是结构示意图的判断、离子结构中存在的等量关系,这是未来考试中的必考考点,也是非常容易出错的地方

         有关离子结构与原子结构示意图、化学反应的微观模型示意图,这个知识点是我们后期一次月考、二次月考、期中考试、期末考试甚至是中考都考到的内容,希望同学们一次把它吃透,给我们秋季课堂内容奠定一个重要的基础。

    f753c94e94aab3ae6363874395d2570a.png “原子结构及离子”思维导图图片

    “原子结构及离子”课堂内容回放

    今天的分享就到这里了,期待各位家长及同学们持续关注,共同学习!

        在此过程中,全部都是邵文老师一个人在打造这个公众号(非常感谢同学们的班主任王贤老师给予的支持和推广),难免会出现一些错误,还请同学们指证出来的同时,给予邵文老师一颗包容体谅的心,邵文老师一定会努力去做好。

        欢迎各位家长及广大同学们进行留言,大家的鼓励将是邵文老师努力的动力,再次谢谢大家!

    展开全文
  • Atomic 原子

    2020-08-21 09:36:18
    在化学上,我们知道原子构成一般物质的最小单位,在化学反应中是不可分割的。在我们这里 Atomic 是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。 所以,...

    1 Atomic 原子类介绍

    Atomic 翻译成中文是原子的意思。在化学上,我们知道原子是构成一般物质的最小单位,在化学反应中是不可分割的。在我们这里 Atomic 是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。

    所以,所谓原子类说简单点就是具有原子/原子操作特征的类。

    并发包 java.util.concurrent 的原子类都存放在java.util.concurrent.atomic下,如下图所示。

    JUC原子类概览

    根据操作的数据类型,可以将JUC包中的原子类分为4类

    基本类型

    使用原子的方式更新基本类型

    • AtomicInteger:整型原子类
    • AtomicLong:长整型原子类
    • AtomicBoolean :布尔型原子类

    数组类型

    使用原子的方式更新数组里的某个元素

    • AtomicIntegerArray:整型数组原子类
    • AtomicLongArray:长整型数组原子类
    • AtomicReferenceArray :引用类型数组原子类

    引用类型

    • AtomicReference:引用类型原子类
    • AtomicMarkableReference:原子更新带有标记的引用类型。该类将 boolean 标记与引用关联起来,也可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。
    • AtomicStampedReference :原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于解决原子的更新数据和数据的版本号,可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。

    对象的属性修改类型

    • AtomicIntegerFieldUpdater:原子更新整型字段的更新器
    • AtomicLongFieldUpdater:原子更新长整型字段的更新器
    • AtomicReferenceFieldUpdater:原子更新引用类型里的字段

    修正: AtomicMarkableReference 不能解决ABA问题 issue#626

        /**
    
    AtomicMarkableReference是将一个boolean值作是否有更改的标记,本质就是它的版本号只有两个,true和false,
    
    修改的时候在这两个版本号之间来回切换,这样做并不能解决ABA的问题,只是会降低ABA问题发生的几率而已
    
    @author : Jack Li
    
    @Date : 2020/1/17 14:41
    */
    
    public class SolveABAByAtomicMarkableReference {
           
           private static AtomicMarkableReference atomicMarkableReference = new AtomicMarkableReference(100, false);
    
            public static void main(String[] args) {
    
                Thread refT1 = new Thread(() -> {
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    atomicMarkableReference.compareAndSet(100, 101, atomicMarkableReference.isMarked(), !atomicMarkableReference.isMarked());
                    atomicMarkableReference.compareAndSet(101, 100, atomicMarkableReference.isMarked(), !atomicMarkableReference.isMarked());
                });
    
                Thread refT2 = new Thread(() -> {
                    boolean marked = atomicMarkableReference.isMarked();
                    try {
                        TimeUnit.SECONDS.sleep(2);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    boolean c3 = atomicMarkableReference.compareAndSet(100, 101, marked, !marked);
                    System.out.println(c3); // 返回true,实际应该返回false
                });
    
                refT1.start();
                refT2.start();
            }
        }
    

    CAS ABA 问题

    • 描述: 第一个线程取到了变量 x 的值 A,然后巴拉巴拉干别的事,总之就是只拿到了变量 x 的值 A。这段时间内第二个线程也取到了变量 x 的值 A,然后把变量 x 的值改为 B,然后巴拉巴拉干别的事,最后又把变量 x 的值变为 A (相当于还原了)。在这之后第一个线程终于进行了变量 x 的操作,但是此时变量 x 的值还是 A,所以 compareAndSet 操作是成功。
    • 例子描述(可能不太合适,但好理解): 年初,现金为零,然后通过正常劳动赚了三百万,之后正常消费了(比如买房子)三百万。年末,虽然现金零收入(可能变成其他形式了),但是赚了钱是事实,还是得交税的!
    • 代码例子(以AtomicInteger为例)
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class AtomicIntegerDefectDemo {
        public static void main(String[] args) {
            defectOfABA();
        }
    
        static void defectOfABA() {
            final AtomicInteger atomicInteger = new AtomicInteger(1);
    
            Thread coreThread = new Thread(
                    () -> {
                        final int currentValue = atomicInteger.get();
                        System.out.println(Thread.currentThread().getName() + " ------ currentValue=" + currentValue);
    
                        // 这段目的:模拟处理其他业务花费的时间
                        try {
                            Thread.sleep(300);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
    
                        boolean casResult = atomicInteger.compareAndSet(1, 2);
                        System.out.println(Thread.currentThread().getName()
                                + " ------ currentValue=" + currentValue
                                + ", finalValue=" + atomicInteger.get()
                                + ", compareAndSet Result=" + casResult);
                    }
            );
            coreThread.start();
    
            // 这段目的:为了让 coreThread 线程先跑起来
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            Thread amateurThread = new Thread(
                    () -> {
                        int currentValue = atomicInteger.get();
                        boolean casResult = atomicInteger.compareAndSet(1, 2);
                        System.out.println(Thread.currentThread().getName()
                                + " ------ currentValue=" + currentValue
                                + ", finalValue=" + atomicInteger.get()
                                + ", compareAndSet Result=" + casResult);
    
                        currentValue = atomicInteger.get();
                        casResult = atomicInteger.compareAndSet(2, 1);
                        System.out.println(Thread.currentThread().getName()
                                + " ------ currentValue=" + currentValue
                                + ", finalValue=" + atomicInteger.get()
                                + ", compareAndSet Result=" + casResult);
                    }
            );
            amateurThread.start();
        }
    }
    

    输出内容如下:

    Thread-0 ------ currentValue=1
    Thread-1 ------ currentValue=1, finalValue=2, compareAndSet Result=true
    Thread-1 ------ currentValue=2, finalValue=1, compareAndSet Result=true
    Thread-0 ------ currentValue=1, finalValue=2, compareAndSet Result=true
    

    下面我们来详细介绍一下这些原子类。

    2 基本类型原子类

    2.1 基本类型原子类介绍

    使用原子的方式更新基本类型

    • AtomicInteger:整型原子类
    • AtomicLong:长整型原子类
    • AtomicBoolean :布尔型原子类

    上面三个类提供的方法几乎相同,所以我们这里以 AtomicInteger 为例子来介绍。

    AtomicInteger 类常用方法

    public final int get() //获取当前的值
    public final int getAndSet(int newValue)//获取当前的值,并设置新的值
    public final int getAndIncrement()//获取当前的值,并自增
    public final int getAndDecrement() //获取当前的值,并自减
    public final int getAndAdd(int delta) //获取当前的值,并加上预期的值
    boolean compareAndSet(int expect, int update) //如果输入的数值等于预期值,则以原子方式将该值设置为输入值(update)
    public final void lazySet(int newValue)//最终设置为newValue,使用 lazySet 设置之后可能导致其他线程在之后的一小段时间内还是可以读到旧的值。
    

    2.2 AtomicInteger 常见方法使用

    import java.util.concurrent.atomic.AtomicInteger;
    
    public class AtomicIntegerTest {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		int temvalue = 0;
    		AtomicInteger i = new AtomicInteger(0);
    		temvalue = i.getAndSet(3);
    		System.out.println("temvalue:" + temvalue + ";  i:" + i);//temvalue:0;  i:3
    		temvalue = i.getAndIncrement();
    		System.out.println("temvalue:" + temvalue + ";  i:" + i);//temvalue:3;  i:4
    		temvalue = i.getAndAdd(5);
    		System.out.println("temvalue:" + temvalue + ";  i:" + i);//temvalue:4;  i:9
    	}
    
    }
    

    2.3 基本数据类型原子类的优势

    通过一个简单例子带大家看一下基本数据类型原子类的优势

    ①多线程环境不使用原子类保证线程安全(基本数据类型)

    class Test {
            private volatile int count = 0;
            //若要线程安全执行执行count++,需要加锁
            public synchronized void increment() {
                      count++; 
            }
    
            public int getCount() {
                      return count;
            }
    }
    

    ②多线程环境使用原子类保证线程安全(基本数据类型)

    class Test2 {
            private AtomicInteger count = new AtomicInteger();
    
            public void increment() {
                      count.incrementAndGet();
            }
          //使用AtomicInteger之后,不需要加锁,也可以实现线程安全。
           public int getCount() {
                    return count.get();
            }
    }
    
    

    2.4 AtomicInteger 线程安全原理简单分析

    AtomicInteger 类的部分源码:

        // setup to use Unsafe.compareAndSwapInt for updates(更新操作时提供“比较并替换”的作用)
        private static final Unsafe unsafe = Unsafe.getUnsafe();
        private static final long valueOffset;
    
        static {
            try {
                valueOffset = unsafe.objectFieldOffset
                    (AtomicInteger.class.getDeclaredField("value"));
            } catch (Exception ex) { throw new Error(ex); }
        }
    
        private volatile int value;
    

    AtomicInteger 类主要利用 CAS (compare and swap) + volatile 和 native 方法来保证原子操作,从而避免 synchronized 的高开销,执行效率大为提升。

    CAS的原理是拿期望的值和原本的一个值作比较,如果相同则更新成新的值。UnSafe 类的 objectFieldOffset() 方法是一个本地方法,这个方法是用来拿到“原来的值”的内存地址。另外 value 是一个volatile变量,在内存中可见,因此 JVM 可以保证任何时刻任何线程总能拿到该变量的最新值。

    3 数组类型原子类

    3.1 数组类型原子类介绍

    使用原子的方式更新数组里的某个元素

    • AtomicIntegerArray:整形数组原子类
    • AtomicLongArray:长整形数组原子类
    • AtomicReferenceArray :引用类型数组原子类

    上面三个类提供的方法几乎相同,所以我们这里以 AtomicIntegerArray 为例子来介绍。

    AtomicIntegerArray 类常用方法

    public final int get(int i) //获取 index=i 位置元素的值
    public final int getAndSet(int i, int newValue)//返回 index=i 位置的当前的值,并将其设置为新值:newValue
    public final int getAndIncrement(int i)//获取 index=i 位置元素的值,并让该位置的元素自增
    public final int getAndDecrement(int i) //获取 index=i 位置元素的值,并让该位置的元素自减
    public final int getAndAdd(int i, int delta) //获取 index=i 位置元素的值,并加上预期的值
    boolean compareAndSet(int i, int expect, int update) //如果输入的数值等于预期值,则以原子方式将 index=i 位置的元素值设置为输入值(update)
    public final void lazySet(int i, int newValue)//最终 将index=i 位置的元素设置为newValue,使用 lazySet 设置之后可能导致其他线程在之后的一小段时间内还是可以读到旧的值。
    

    3.2 AtomicIntegerArray 常见方法使用

    
    import java.util.concurrent.atomic.AtomicIntegerArray;
    
    public class AtomicIntegerArrayTest {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		int temvalue = 0;
    		int[] nums = { 1, 2, 3, 4, 5, 6 };
    		AtomicIntegerArray i = new AtomicIntegerArray(nums);
    		for (int j = 0; j < nums.length; j++) {
    			System.out.println(i.get(j));
    		}
    		temvalue = i.getAndSet(0, 2);
    		System.out.println("temvalue:" + temvalue + ";  i:" + i);
    		temvalue = i.getAndIncrement(0);
    		System.out.println("temvalue:" + temvalue + ";  i:" + i);
    		temvalue = i.getAndAdd(0, 5);
    		System.out.println("temvalue:" + temvalue + ";  i:" + i);
    	}
    
    }
    

    4 引用类型原子类

    4.1 引用类型原子类介绍

    基本类型原子类只能更新一个变量,如果需要原子更新多个变量,需要使用 引用类型原子类。

    • AtomicReference:引用类型原子类
    • AtomicStampedReference:原子更新带有版本号的引用类型。该类将整数值与引用关联起来,可用于解决原子的更新数据和数据的版本号,可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。
    • AtomicMarkableReference :原子更新带有标记的引用类型。该类将 boolean 标记与引用关联起来,也可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。

    上面三个类提供的方法几乎相同,所以我们这里以 AtomicReference 为例子来介绍。

    4.2 AtomicReference 类使用示例

    import java.util.concurrent.atomic.AtomicReference;
    
    public class AtomicReferenceTest {
    
    	public static void main(String[] args) {
    		AtomicReference<Person> ar = new AtomicReference<Person>();
    		Person person = new Person("SnailClimb", 22);
    		ar.set(person);
    		Person updatePerson = new Person("Daisy", 20);
    		ar.compareAndSet(person, updatePerson);
    
    		System.out.println(ar.get().getName());
    		System.out.println(ar.get().getAge());
    	}
    }
    
    class Person {
    	private String name;
    	private int age;
    
    	public Person(String name, int age) {
    		super();
    		this.name = name;
    		this.age = age;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public int getAge() {
    		return age;
    	}
    
    	public void setAge(int age) {
    		this.age = age;
    	}
    
    }
    

    上述代码首先创建了一个 Person 对象,然后把 Person 对象设置进 AtomicReference 对象中,然后调用 compareAndSet 方法,该方法就是通过 CAS 操作设置 ar。如果 ar 的值为 person 的话,则将其设置为 updatePerson。实现原理与 AtomicInteger 类中的 compareAndSet 方法相同。运行上面的代码后的输出结果如下:

    Daisy
    20
    

    4.3 AtomicStampedReference 类使用示例

    import java.util.concurrent.atomic.AtomicStampedReference;
    
    public class AtomicStampedReferenceDemo {
        public static void main(String[] args) {
            // 实例化、取当前值和 stamp 值
            final Integer initialRef = 0, initialStamp = 0;
            final AtomicStampedReference<Integer> asr = new AtomicStampedReference<>(initialRef, initialStamp);
            System.out.println("currentValue=" + asr.getReference() + ", currentStamp=" + asr.getStamp());
    
            // compare and set
            final Integer newReference = 666, newStamp = 999;
            final boolean casResult = asr.compareAndSet(initialRef, newReference, initialStamp, newStamp);
            System.out.println("currentValue=" + asr.getReference()
                    + ", currentStamp=" + asr.getStamp()
                    + ", casResult=" + casResult);
    
            // 获取当前的值和当前的 stamp 值
            int[] arr = new int[1];
            final Integer currentValue = asr.get(arr);
            final int currentStamp = arr[0];
            System.out.println("currentValue=" + currentValue + ", currentStamp=" + currentStamp);
    
            // 单独设置 stamp 值
            final boolean attemptStampResult = asr.attemptStamp(newReference, 88);
            System.out.println("currentValue=" + asr.getReference()
                    + ", currentStamp=" + asr.getStamp()
                    + ", attemptStampResult=" + attemptStampResult);
    
            // 重新设置当前值和 stamp 值
            asr.set(initialRef, initialStamp);
            System.out.println("currentValue=" + asr.getReference() + ", currentStamp=" + asr.getStamp());
    
            // [不推荐使用,除非搞清楚注释的意思了] weak compare and set
            // 困惑!weakCompareAndSet 这个方法最终还是调用 compareAndSet 方法。[版本: jdk-8u191]
            // 但是注释上写着 "May fail spuriously and does not provide ordering guarantees,
            // so is only rarely an appropriate alternative to compareAndSet."
            // todo 感觉有可能是 jvm 通过方法名在 native 方法里面做了转发
            final boolean wCasResult = asr.weakCompareAndSet(initialRef, newReference, initialStamp, newStamp);
            System.out.println("currentValue=" + asr.getReference()
                    + ", currentStamp=" + asr.getStamp()
                    + ", wCasResult=" + wCasResult);
        }
    }
    

    输出结果如下:

    currentValue=0, currentStamp=0
    currentValue=666, currentStamp=999, casResult=true
    currentValue=666, currentStamp=999
    currentValue=666, currentStamp=88, attemptStampResult=true
    currentValue=0, currentStamp=0
    currentValue=666, currentStamp=999, wCasResult=true
    

    4.4 AtomicMarkableReference 类使用示例

    import java.util.concurrent.atomic.AtomicMarkableReference;
    
    public class AtomicMarkableReferenceDemo {
        public static void main(String[] args) {
            // 实例化、取当前值和 mark 值
            final Boolean initialRef = null, initialMark = false;
            final AtomicMarkableReference<Boolean> amr = new AtomicMarkableReference<>(initialRef, initialMark);
            System.out.println("currentValue=" + amr.getReference() + ", currentMark=" + amr.isMarked());
    
            // compare and set
            final Boolean newReference1 = true, newMark1 = true;
            final boolean casResult = amr.compareAndSet(initialRef, newReference1, initialMark, newMark1);
            System.out.println("currentValue=" + amr.getReference()
                    + ", currentMark=" + amr.isMarked()
                    + ", casResult=" + casResult);
    
            // 获取当前的值和当前的 mark 值
            boolean[] arr = new boolean[1];
            final Boolean currentValue = amr.get(arr);
            final boolean currentMark = arr[0];
            System.out.println("currentValue=" + currentValue + ", currentMark=" + currentMark);
    
            // 单独设置 mark 值
            final boolean attemptMarkResult = amr.attemptMark(newReference1, false);
            System.out.println("currentValue=" + amr.getReference()
                    + ", currentMark=" + amr.isMarked()
                    + ", attemptMarkResult=" + attemptMarkResult);
    
            // 重新设置当前值和 mark 值
            amr.set(initialRef, initialMark);
            System.out.println("currentValue=" + amr.getReference() + ", currentMark=" + amr.isMarked());
    
            // [不推荐使用,除非搞清楚注释的意思了] weak compare and set
            // 困惑!weakCompareAndSet 这个方法最终还是调用 compareAndSet 方法。[版本: jdk-8u191]
            // 但是注释上写着 "May fail spuriously and does not provide ordering guarantees,
            // so is only rarely an appropriate alternative to compareAndSet."
            // todo 感觉有可能是 jvm 通过方法名在 native 方法里面做了转发
            final boolean wCasResult = amr.weakCompareAndSet(initialRef, newReference1, initialMark, newMark1);
            System.out.println("currentValue=" + amr.getReference()
                    + ", currentMark=" + amr.isMarked()
                    + ", wCasResult=" + wCasResult);
        }
    }
    

    输出结果如下:

    currentValue=null, currentMark=false
    currentValue=true, currentMark=true, casResult=true
    currentValue=true, currentMark=true
    currentValue=true, currentMark=false, attemptMarkResult=true
    currentValue=null, currentMark=false
    currentValue=true, currentMark=true, wCasResult=true
    

    5 对象的属性修改类型原子类

    5.1 对象的属性修改类型原子类介绍

    如果需要原子更新某个类里的某个字段时,需要用到对象的属性修改类型原子类。

    • AtomicIntegerFieldUpdater:原子更新整形字段的更新器
    • AtomicLongFieldUpdater:原子更新长整形字段的更新器
    • AtomicReferenceFieldUpdater :原子更新引用类型里的字段的更新器

    要想原子地更新对象的属性需要两步。第一步,因为对象的属性修改类型原子类都是抽象类,所以每次使用都必须使用静态方法 newUpdater()创建一个更新器,并且需要设置想要更新的类和属性。第二步,更新的对象属性必须使用 public volatile 修饰符。

    上面三个类提供的方法几乎相同,所以我们这里以 AtomicIntegerFieldUpdater为例子来介绍。

    5.2 AtomicIntegerFieldUpdater 类使用示例

    import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
    
    public class AtomicIntegerFieldUpdaterTest {
    	public static void main(String[] args) {
    		AtomicIntegerFieldUpdater<User> a = AtomicIntegerFieldUpdater.newUpdater(User.class, "age");
    
    		User user = new User("Java", 22);
    		System.out.println(a.getAndIncrement(user));// 22
    		System.out.println(a.get(user));// 23
    	}
    }
    
    class User {
    	private String name;
    	public volatile int age;
    
    	public User(String name, int age) {
    		super();
    		this.name = name;
    		this.age = age;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public int getAge() {
    		return age;
    	}
    
    	public void setAge(int age) {
    		this.age = age;
    	}
    
    }
    

    输出结果:

    22
    23
    
    展开全文
  • 分子 原子 离子C卷 1.下列叙述中不正确的是 A钠原子失去电子后变成钠离子 B氯离子失去电子后变成氯原子 C原子的质量主要集中在原子核上 D化学变化中分子不能再...根据钠原子结构示意判断下列说法错误的是( ) A.钠原子
  • 在化学上,我们知道原子构成一般物质的最小单位,在化学反应中是不可分割的。在我们这里 Atomic 是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。 所以,...

    1.介绍一下 Atomic 原子类

    Atomic 翻译成中文是原子的意思。在化学上,我们知道原子是构成一般物质的最小单位,在化学反应中是不可分割的。在我们这里 Atomic 是指一个操作是不可中断的。即使是在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰。

    所以,所谓原子类说简单点就是具有原子 / 原子操作特征的类。

    并发包 java.util.concurrent 的原子类都存放在 java.util.concurrent.atomic 下,如下图所示:

    在这里插入图片描述

    2. JUC 包中的原子类是哪4类?

    2.1. 基本类型

    使用原子的方式更新基本类型:

    • AtomicInteger : 整型原子类
    • AtomicLong: 长整型原子类
    • AtomicBoolean: 布尔型原子类

    2.2.数组类型

    使用原子的方式更新数组里的某个元素:

    • AtomicIntegerArray: 整型数组原子类
    • AtomicLongArray: 长整型数组原子类
    • AtomicReferenceArray: 引用类型数组原子类

    2.3. 引用类型

    使用原子的方式更新引用类型:

    • AtomicReference: 引用类型原子类
    • AtomicStampedReference: 原子更新带有版本号的引用类型。该类将整型数值与引用关联起来,可用于解决原子的更新数据和数据的版本号,可以解决使用 CAS 进行原子更新时可能出现的 ABA 问题。
    • AtomicMarkableReference: 原子更新带有标记位的引用类型。

    2.4.对象属性修改类型

    • AtomicIntegerFieldUpdater: 原子更新整型字段的更新器
    • AtomicLongFieldUpdater: 原子更新长整型字段的更新器
    • AtomicMarkableReference: 原子更新带有标记位的引用类型

    3. 讲一下 AtomicInteger 的使用

    AtomicInteger 类常用方法:

    // 获取当前的值
    public final int get()
    
    // 获取当前的值,并设置新的值
    public final int getAndSet(int newValue)
      
    // 获取当前的值,并自增
    public final int getAndIncrement()
    
    // 获取当前的值,并自减
    public final int getAndDecrement()
      
    // 获取当前的值,并加上delta
    public final int getAndAdd(int delta)
      
    // 如果输入的数值等于预期值(expect),则以原子方式将该值设置为输入值(update)
    boolean compareAndSet(int expect , int update)
      
    // 最终设置为newValue,使用lazySet设置之后可能导致其他线程在之后的一小段时间还是可以读到旧的值
    public final void lazySet(int newValue)
    

    AtomicInteger 类的使用示例:

    使用 AtomicInteger 之后,不用对 increment() 方法加锁也可以保证线程安全:

    class AtomicIntegerTest {
        private AtomicInteger count = new AtomicInteger();
    
        //使用AtomicInteger之后,不需要对该方法加锁,也可以实现线程安全。
        public void increment() {
          count.incrementAndGet();
        }
    
        public int getCount() {
          return count.get();
        }
    }
    

    4.简单介绍一下 AtomicInteger 类的原理

    AtomicInteger 线程安全原理简单分析,AtomicInteger 类的部分源码:

      // 更新操作时提供“比较并替换”的作用
      private static final Unsafe unsafe = Unsafe.getUnsafe();
    
      private static final long valueOffset;
    
      static {
          try{
              valueOffset = unsafe.objectFieldOffset(AutomicInteger.class.getDeclaredField("value"));
          }catch(Exception ex){
              throw new Error(ex);
          }
      }
    
      private volatile int value;
    

    AtomicInteger 类主要利用 CAS(compare and swap) + volatilenative 方法来保证原子操作,从而避免 synchronized 的高开销,执行效率大为提升。

    CAS 的原理是: 拿期望的值和原本的一个值作比较,如果相同则更新成新的值。Unsafe 类的 ObjectFieldOffset() 方法是一个本地方法,这个方法用来拿到 “原来的值” 的内存地址,返回值是 valueOffset。另外,value 是一个 volatile 变量,在内存中可见,因此 JVM 可以保证任何时刻任何线程总能拿到该变量的最新值。

    5. 总结

    本篇文章讲解了Java多线程进阶面试题-Atomic原子类。代码和笔记由于纯手打,难免会有纰漏,如果发现错误的地方,请第一时间告诉我,这将是我进步的一个很重要的环节。以后会定期更新算法题目以及各种开发知识点,如果您觉得写得不错,不妨点个关注,谢谢。

    展开全文
  • 在1920年代,路易斯·德布罗意(Louis de Broglie)的观察发现,可能与氢原子发射的各种电磁能量子产生的干涉有关的整数序列与众所周知的经典共振过程的整数序列相同,这使他得出结论,电子是俘虏的在原子内处于...
  • 原子结构,半导体,PN结到MOS管和CMOS

    千次阅读 多人点赞 2018-03-23 12:56:20
    原子原子核和围绕原子核旋转的电子构成。如果将原子比作一棒球场,那么原子核大大小不比一个棒球大,但原子的所有重量都集中在原子核上,而电子只相当于棒球场上的苍蝇,所占空间相比来说也是极...
  • React原子设计 这是Atomic Design方法的样板,其中使用了一些很酷的东西,例如Storybook,Flow和CSS Modules。 随时进行测试,更改并适应一切。... 有机体是一起工作的分子甚至与构成更复杂界面的原子的结合。 在这个
  • 用例为宏观 用例不能用名词,可以用动词或者动名词。 用例是参与者与系统之间的一组交互的动作序列 这组动作要借助IT技术得以实现,要体现出客户价值(提升客户的工作效率,提高客户的效益 ...非原子性的动词才能
  • 【能带结构绘图和初步分析】1.1能带简介在形成分子时,原子轨道构成具有分立能级的分子轨道。晶体是由大量的原子有序堆积而成的。由原子轨道所构成的分子轨道的数量非常之大,以至于可以将所形成的分子轨道的能级...
  • 辅助模型——活动

    2019-08-01 19:39:33
    活动是描述动作,动作的执行顺序以及动作的输入和输出的,它由节点和边这两种基本元素构成。 动作是行为规范的基础单元,用以描述系统中的活动,它是原子的和即时的。 活动是由一系列的动作构成的(也称为动作...
  • 动作是原子的,不可以分解成更小单位 动作是不可中断的 动作是瞬时完成的行为 动作可以没有入转换,但至少有一条出转换 动作不能有入口动作和出口动作 在一张活动中,动作允许出现多次 【图形】平滑的圆角矩形 2....
  • Neo4j主要通过构成图来存储数据,图中的数据包括节点、关系以及节点的属性和关系的属性,关系可以是双向的,也可以是只有单向的. 以下是它的一些特点 支持完整的ACID(原子性、一致性、隔离性和持久性) 支持常数...
  • 构造一张(由顶点、边构成),假设里面有5个三角形,只增加1条边,就让三角形的个数倍增为10, 请画出这张图的结构来? 先决条件:这张图里面,顶点为账户,边为账户间的交易,账户间可以有多笔交易。所谓的...
  • 1.1 能带简介在形成分子时,原子轨道构成具有分立能级的分子轨道。晶体是由大量的原子有序堆积而成的。由原子轨道所构成的分子轨道的数量非常之大,以至于可以将所形成的分子轨道的能级看成是准连续的,即形成了能带...
  • 这些事物又是什么构成的呢?他们最基本的特性为什么是这样的呢?他们又是哪些化学元素构成的呢?这些元素又是什么分子结构的呢?这些分子机构又有多少种类的原子呢?这些原子里又有多少中子和质子呢?……诗人用字...
  • 一.Huckel规则定义 含有4n+2(n=0,1,2,…)电子的单环封闭平面共轭多烯化合物具有芳香性。... 例如苯的结构式为: 苯环由6个碳原子构成,它们之间的键是单双建交替的,这就是所谓的共轭多烯结构。 ...
  • 2、概念:描述动作、动作的执行顺序以及动作的输入与输出的,它由节点和边这两种基本元素构成 3、动作:行为规约的基础单元,用以描述系统中的活动,是原子的(在当前的抽象层次上,动作是不可间断的)和即时的...
  • 我们无时无刻不在面临着关系数据:构成物质的分子是一种由各种原子组成的关系网络;人类社会是一种以人为节点组成的社交网络;整个宇宙更是一种异质、非均匀的大型网络。有实体的地方一定有关系,关系中同样蕴藏着...
  • 当穿过构成IC的材料层时,电离粒子(例如高能光子(x和γ射线)和带电粒子(电子、质子、重离子…)通过产生电子-空穴对而损失大部分能量。这种过量的电荷载流子可以通过诱发单事件效应(见〔16〕(及其参考文献)...
  • 深度学习模型---稀疏编码 Sparse Coding

    千次阅读 2017-10-26 09:59:35
    前言  本文的理论部分主要整理自UFLDL的“Sparse Coding”章节和一些经典教材,同时也参考了网上的一些经典博客,包含了Sparse Coding的一些...D为标准化的基础矩阵,由组成元素的基本原子构成,也称为字典。在...
  • 电介质(绝缘体):不导电的物质,其中的电荷被束缚在原子范围内不能宏观移动束缚电荷(极化电荷):电介质中被束缚的电荷极化:原先宏观上处处电中性的导体或电介质,在外电场的作用下,达到平衡后,出现某种宏观的...
  • [FJOI2007]轮状病毒

    2019-10-05 00:19:17
    一个n轮状基由圆环上n个不同的基原子和圆心的一个核原子构成。2个原子之间的边表示这2个原子之间的信息通道,如1。 n轮状病毒的产生规律是在n轮状基中删除若干边,使各原子之间有唯一一条信息通道。例如,共有16...
  • 一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道。如下所示 N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,...
  • 一个n轮状基由圆环上n个不同的基原子和圆心的一个核原子构成。2个原子之间的边表示这2个原子之间的信息通道,如1。 n轮状病毒的产生规律是在n轮状基中删除若干边,使各原子之间有唯一一条信息通道。例如,共有16...
  • 一个nnn轮状基由圆环上nnn个不同的基原子和圆心的一个核原子构成。222个原子之间的边表示这222个原子之间的信息通道,如111。 nnn轮状病毒的产生规律是在nnn轮状基中删除若干边,使各原子之间有唯一一条信息通道...
  • 一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道。如下所示  N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道...

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 186
精华内容 74
关键字:

原子构成图