Java:从单线程计数器到多线程数据同步synchronized和原子类Atomic

简介: Java:从单线程计数器到多线程数据同步synchronized和原子类Atomic
+关注继续查看

目录

使用单线程

使用多线程

使用多线程 + synchronized

使用多线程 + 原子类AtomicLong

使用单线程

单线程修改计数器的值,没有发生问题,每次运行结果都是10000,不过程序耗时较长


package com.example;


/**

* 计数器

*/

class Counter {

   private static long count;


   public static long getCount() {

       return count;

   }


   public static void incrementCount() {

       count++;

   }

}



public class Demo {

   public static void main(String[] args) throws InterruptedException {

       long count = Counter.getCount();

       System.out.println(count);

       // 0


       for (int i = 0; i < 10000; i++) {

           try {

               Thread.sleep(1);

           } catch (InterruptedException e) {

               e.printStackTrace();

           }

           Counter.incrementCount();

       }

       

       count = Counter.getCount();

       System.out.println(count);

       // 10000

   }

}



使用多线程

单线程修改计数器的值,运行速度提高了,不过运行结果每次都不一致,而且结果不是10000


package com.example;


import java.util.ArrayList;

import java.util.List;


/**

* 计数器

*/

class Counter {

   private static long count;


   public static long getCount() {

       return count;

   }


   public static void incrementCount() {

       count++;

   }

}



public class Demo {

   public static void main(String[] args) throws InterruptedException {

       long count = Counter.getCount();

       System.out.println(count);

       // 0


       List<Thread> list = new ArrayList<>();


       // 启动10000个线程同时访问计数器

       for (int i = 0; i < 10000; i++) {

           Thread thread = new Thread(new Runnable() {

               @Override

               public void run() {

                   try {

                       Thread.sleep(1);

                   } catch (InterruptedException e) {

                       e.printStackTrace();

                   }

                   Counter.incrementCount();

               }

           });

           list.add(thread);

       }


       for (Thread thread : list) {

           thread.start();

       }


       for (Thread thread : list) {

           thread.join();

       }


       count = Counter.getCount();

       System.out.println(count);

   }


执行结果


第一次:9910

第二次:9912

第三次:9910


使用多线程 + synchronized

多线程加锁后,最后结果都是10000


package com.example;


import java.util.ArrayList;

import java.util.List;


/**

* 计数器

*/

class Counter {

   private static long count;


   public static long getCount() {

       return count;

   }


   public static synchronized void incrementCount() {

       count++;

   }

}



public class Demo {

   public static void main(String[] args) throws InterruptedException {

       long count = Counter.getCount();

       System.out.println(count);

       // 0


       List<Thread> list = new ArrayList<>();


       // 启动10000个线程同时访问计数器

       for (int i = 0; i < 10000; i++) {

           Thread thread = new Thread(new Runnable() {

               @Override

               public void run() {

                   try {

                       Thread.sleep(1);

                   } catch (InterruptedException e) {

                       e.printStackTrace();

                   }

                   Counter.incrementCount();

               }

           });

           list.add(thread);

       }


       for (Thread thread : list) {

           thread.start();

       }


       for (Thread thread : list) {

           thread.join();

       }


       count = Counter.getCount();

       System.out.println(count);

   }

}


执行结果


第一次:10000

第二次:10000

第三次:10000


使用多线程 + 原子类AtomicLong

多线程中使用原子类AtomicLong实现计数器,最后结果都是10000


原理是CAS(Compare and Set):


先比较原始值和预期值,如果相等,则修改为新值;

不相等则修改失败

伪代码如下


bool compareAndSet(oldValue, expectValue, updateValue){

   if(oldValue == expectValue){

       oldValue = updateValue

       // update success

   } else{

       // update fail

   }

}


package com.example;


import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.atomic.AtomicLong;


/**

* 计数器

*/

class Counter {

   private static AtomicLong count = new AtomicLong(0);


   public static long getCount() {

       return count.get();

   }


   public static void incrementCount() {

       count.incrementAndGet();

   }

}



public class Demo {

   public static void main(String[] args) throws InterruptedException {

       long count = Counter.getCount();

       System.out.println(count);

       // 0


       List<Thread> list = new ArrayList<>();


       // 启动10000个线程同时访问计数器

       for (int i = 0; i < 10000; i++) {

           Thread thread = new Thread(new Runnable() {

               @Override

               public void run() {

                   try {

                       Thread.sleep(1);

                   } catch (InterruptedException e) {

                       e.printStackTrace();

                   }

                   Counter.incrementCount();

               }

           });

           list.add(thread);

       }


       for (Thread thread : list) {

           thread.start();

       }


       for (Thread thread : list) {

           thread.join();

       }


       count = Counter.getCount();

       System.out.println(count);

   }

}


执行结果


第一次:10000

第二次:10000

第三次:10000

————————————————

版权声明:本文为CSDN博主「彭世瑜」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/mouday/article/details/130923836

相关文章
|
12天前
|
Java
Java实现计数器
Java实现计数器可以使用以下代码
|
2月前
|
算法 Java
第二季:3原子类AtomicInteger的ABA问题谈谈?原子更新引用知道吗?【Java面试题】
第二季:3原子类AtomicInteger的ABA问题谈谈?原子更新引用知道吗?【Java面试题】
21 0
|
4月前
|
算法 安全 Java
【Java并发编程 八】JUC并发包下原子类
【Java并发编程 八】JUC并发包下原子类
33 0
|
5月前
|
Java 开发工具
Java的Atomic原子类
Java SDK 并发包里提供了丰富的原子类,我们可以将其分为五个类别,这五个类别提供的方法基本上是相似的,并且每个类别都有若干原子类。
Java的Atomic原子类
|
5月前
|
安全 Java 大数据
大数据开发基础的编程语言的Java的并发/多线程编程的原子类
在Java并发编程中,原子类是一种非常重要的机制,用于保证多个线程之间对于共享变量的访问的原子性。本文将介绍Java的原子类以及如何使用原子类进行多线程编程。
38 0
|
8月前
|
安全 算法 Java
Java规则:原子类的相等性判断
Java规则:原子类的相等性判断
Java规则:原子类的相等性判断
|
12月前
|
存储 安全 Java
java并发原理实战(7) -- 原子类使用和原理理解
java并发原理实战(7) -- 原子类使用和原理理解
java并发原理实战(7) -- 原子类使用和原理理解
|
安全 Java
java并发原子类AtomicBoolean解析
如果看过我之前的文章都知道这几天一直在更新java多线程这块的知识点,因为这块的知识点确实是比较多而且也别繁杂,因此对于java多线程基础知识点也会在两个多月的时间全部写完,这篇文章主要是针对java并发包下的一个原子类AtomicBoolean的讲解。
159 0
java并发原子类AtomicBoolean解析
|
安全 算法 Java
详解java并发原子类AtomicInteger(基于jdk1.8源码分析)
java并发包里面的类一直是学习和面试的重点,这篇文章主要是对java并发包的其中一个类AtomicInteger的讲解。从为什么要出现AtomicInteger再到其底层原理来一个分析。
191 0
详解java并发原子类AtomicInteger(基于jdk1.8源码分析)
|
安全 Java C++
「死磕Java并发编程」说说Java Atomic 原子类的实现原理
「死磕Java并发编程」说说Java Atomic 原子类的实现原理
「死磕Java并发编程」说说Java Atomic 原子类的实现原理
推荐文章
更多