AtomicInteger线程安全的操作加减
参考链接:https://blog.csdn.net/z834410038/article/details/73550760
AtomicInteger,一个提供原子操作的Integer的类。在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口。
下面通过简单的例子对比来看一下 AtomicInteger 的强大的功能。
下面看一个没有做现成安全的例子:
package com; public class AtomicIntegerTest3 { /** * 这里模拟一个递增的任务,开启10个线程每个线程减去10,总数为300。 * 最终结果正确是200 */ public static void main(String[] args) throws InterruptedException { MyThreadDemo myThreadDemo = new MyThreadDemo(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); Thread.sleep(5000);//主线程休眠5秒,得到最后结果 System.out.println("执行结果:count=" + myThreadDemo.getCount()); } } class MyThreadDemo implements Runnable{ private int count = 300;//初始值300,被10个线程共享 private void decrement(int i) { count --; System.out.println(Thread.currentThread().getName()+"执行"+i+"次,剩余count:"+count); } public int getCount() { return count; } @Override public void run() { try { Thread.sleep(100);//每个子线程进来先休眠100毫秒,模拟网络环境 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(int i=1;i<=10;i++) { decrement(i); } } }
可以看到结果次线程并没有预期的结果200,原因是线程不安全 。并且线程打印输出也没有顺序打印,可以看见cpu对于线程分配资源是多麽随意。
synchronized关键字实现线程同步:
package com; public class AtomicIntegerTest3 { /** * 这里模拟一个递增的任务,开启10个线程每个线程减去10,总数为300。 * 最终结果正确是200 */ public static void main(String[] args) throws InterruptedException { MyThreadDemo myThreadDemo = new MyThreadDemo(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); Thread.sleep(5000);//主线程休眠5秒,得到最后结果 System.out.println("执行结果:count=" + myThreadDemo.getCount()); } } class MyThreadDemo implements Runnable{ private int count = 300;//初始值300,被10个线程共享 private synchronized void decrement(int i) { count --; System.out.println(Thread.currentThread().getName()+"执行"+i+"次,剩余count:"+count); } public int getCount() { return count; } @Override public void run() { try { Thread.sleep(100);//每个子线程进来先休眠100毫秒,模拟网络环境 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(int i=1;i<=10;i++) { decrement(i); } } }
执行结果很完美正确的,线程安全。得到预期的结果,并且由于synchronized是是在方法上,所以连输出都变得有顺序。
AtomicInteger关键字实现同步
package com; import java.util.concurrent.atomic.AtomicInteger; public class AtomicIntegerTest3 { /** * 这里模拟一个递增的任务,开启10个线程每个线程减去10,总数为300。 * 最终结果正确是200 */ public static void main(String[] args) throws InterruptedException { MyThreadDemo myThreadDemo = new MyThreadDemo(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); new Thread(myThreadDemo).start(); Thread.sleep(5000);//主线程休眠5秒,得到最后结果 System.out.println("执行结果:count=" + myThreadDemo.getCount()); } } class MyThreadDemo implements Runnable{ private AtomicInteger count = new AtomicInteger(300);//初始值300为10个线程共享 private void decrement(int i) { count.decrementAndGet(); System.out.println(Thread.currentThread().getName()+"执行"+i+"次,剩余count:"+count.get()); } public int getCount() { return count.get(); } @Override public void run() { try { Thread.sleep(100);//每个子线程进来先休眠100毫秒,模拟网络环境 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } for(int i=1;i<=10;i++) { decrement(i); } } }
可以看到执行结果,为预期的200.但是顺序不正确,但是这个是正常的。因为AtomicInteger 同步的范围指针对于这个它本身的变量去同步的。当然没有同步打印的语句了。对于数据本身来说已经做到线程安全了。
AtomicInteger 申明变量,执行count.decrementAndGet();就相当于同步代码块:
synchronized { count -- ; }
看到此代码块只是同步了自减操作。
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)
但是重点注意:AtomicInteger只能在操作当中当中控制操作的原子性,只是针对于自增、自减操作;除此之外不能使线程其他地方进行同步,例如输出语句、线程的访问先后。
相关推荐
Java AtomicInteger类的使用方法详解 Java AtomicInteger类是Java中提供的一种原子操作的Integer类,通过线程安全的方式操作加减。它可以在高并发情况下使用,提供原子操作来进行Integer的使用。 Atomicinteger类...
例如,AtomicInteger是一个提供原子操作的int值类,其addAndGet方法就使用了CAS机制。通过这个类,可以在不需要显式锁的情况下,完成多线程间的数值操作。 总结来说,Java的CAS机制和原子类为我们提供了一种高效...
Java并发编程专题(十)----(JUC原子类)基本类型详解 本资源主要介绍了Java JUC原子类基本类型的相关知识点,包括AtomicInteger、AtomicLong、AtomicBoolean等基本类型的使用方法和原理。通过对原子操作和 일반操作...
1. AtomicInteger、AtomicLong、AtomicReference等,这些原子类提供了一些原子操作,可以用来实现原子性。 2. 这些原子类可以用来解决线程安全问题,例如,使用AtomicInteger可以实现原子性的自增操作。 五、Java中...
1. `AtomicBoolean`, `AtomicInteger`, `AtomicLong`: 这些类分别提供了对布尔值、整型和长整型的原子操作。它们提供了`get()`, `set()`, `compareAndSet()`, `incrementAndGet()`等方法,这些方法在多线程环境下...
AtomicInteger 类通过使用 Unsafe 类的 compareAndSwapInt 方法来实现 CAS 操作。compareAndSwapInt 方法将内存地址的值与预期原值比较,如果相匹配,则更新为新值。 Hotspot 源码中关于 unsafe 的实现,在 hotspot...
12. 计数器模式:用Atomic类如AtomicInteger、AtomicLong实现线程安全的计数操作,避免synchronized的开销。 全书总结部分则对上述内容进行了归纳和提炼,强调了在实际应用中选择合适的设计模式和最佳实践的重要性...
【JAVA初级面试题(release)】相关知识点详解 在Java初级面试中,考察的知识点广泛且基础,旨在评估应聘者对编程语言基本概念的理解以及实际编程能力。以下是一些核心的Java基础知识,这些内容通常会出现在笔试题...
### Java多线程编程详解 #### 一、理解多线程机制 多线程是一种让程序能够并发执行多个指令流的机制,每一个这样的指令流被称为一个线程,它们彼此独立运行。线程与进程相似之处在于都有独立的执行控制,但不同的...
原子性操作(如AtomicInteger)则可以保证在多线程环境下的原子性。 6. 线程中断与守护线程 Thread类提供了interrupt()方法用于中断线程,但需要注意的是,这并不意味着线程会立即停止,而是在线程检查到中断标志后...
2. 并发控制的原子类(如AtomicInteger):这类类封装了基本数据类型,通过无锁的CAS(Compare And Swap)操作保证操作的原子性。 五、线程安全的单例模式 在多线程环境中,单例模式需要特别注意线程安全问题。 1....
- **Atomic类**:如`AtomicInteger`,提供原子操作,适用于轻量级同步。 - **线程局部变量**:`ThreadLocal`类,为每个线程创建独立的变量副本,避免线程间的数据干扰。 6. **死锁问题** - **死锁定义**:两个或...
Java并发工具包J.U.C(Java Util Concurrency)包含了丰富的一系列并发组件,如Lock框架(ReentrantLock等)、并发集合(ConcurrentHashMap等)、原子类(AtomicInteger等)、线程池(ExecutorService)和工具类。...
### 并发编程之CAS与Atomic原子操作详解 #### 一、原子操作的概念与意义 在计算机科学领域,原子操作是指一系列的操作被视为一个整体,在执行过程中不会被其他进程或线程打断的操作。简而言之,它确保了一系列操作...
`ctl`变量在`ThreadPoolExecutor`类中被声明为一个`AtomicInteger`类型,并且被初始化为一个特定的值。这个值是由`ctlOf`方法计算出来的,该方法将线程池的运行状态(`runState`)和工作线程数(`workerCount`)打包...
- **原子类**:如`AtomicInteger`等,提供原子操作的方法。 #### 九、线程数据传递 线程之间的数据传递可以通过以下几种方式实现: - **共享内存**:多个线程共享相同的内存区域,通过读写共享变量实现数据交换。...
例如,使用AtomicBoolean类可以实现锁机制,使用AtomicInteger类可以实现计数器等。 CAS技术的优点 CAS技术的优点是可以在多线程环境中确保原子操作的正确执行,提高了程序的稳定性和可靠性。同时,CAS技术也可以...
1. java.util.concurrent - Java 并发工具包 2. 阻塞队列 BlockingQueue 3. 数组阻塞队列 ArrayBlockingQueue ...23. 原子性整型 AtomicInteger 24. 原子性长整型 AtomicLong 25. 原子性引用型 AtomicReference