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

相关文章
|
7天前
|
安全 Java 调度
Java编程时多线程操作单核服务器可以不加锁吗?
Java编程时多线程操作单核服务器可以不加锁吗?
21 2
|
13天前
|
Java 开发者
Java中的多线程基础与应用
【9月更文挑战第22天】在Java的世界中,多线程是一块基石,它支撑着现代并发编程的大厦。本文将深入浅出地介绍Java中多线程的基本概念、创建方法以及常见的应用场景,帮助读者理解并掌握这一核心技术。
|
9天前
|
Java 调度
Java-Thread多线程的使用
这篇文章介绍了Java中Thread类多线程的创建、使用、生命周期、状态以及线程同步和死锁的概念和处理方法。
Java-Thread多线程的使用
|
15天前
|
Java
领略Lock接口的风采,通过实战演练,让你迅速掌握这门高深武艺,成为Java多线程领域的武林盟主
领略Lock接口的风采,通过实战演练,让你迅速掌握这门高深武艺,成为Java多线程领域的武林盟主
23 7
|
14天前
|
Java 程序员
Java中的多线程基础与实践
【9月更文挑战第21天】本文旨在引导读者深入理解Java多线程的核心概念,通过生动的比喻和实例,揭示线程创建、同步机制以及常见并发工具类的使用。文章将带领读者从理论到实践,逐步掌握如何在Java中高效地运用多线程技术。
|
12天前
|
Java 调度 开发者
Java中的多线程编程:从基础到实践
本文旨在深入探讨Java多线程编程的核心概念和实际应用,通过浅显易懂的语言解释多线程的基本原理,并结合实例展示如何在Java中创建、控制和管理线程。我们将从简单的线程创建开始,逐步深入到线程同步、通信以及死锁问题的解决方案,最终通过具体的代码示例来加深理解。无论您是Java初学者还是希望提升多线程编程技能的开发者,本文都将为您提供有价值的见解和实用的技巧。
15 2
|
14天前
|
Java 数据处理
Java中的多线程编程:从基础到实践
本文旨在深入探讨Java中的多线程编程,涵盖其基本概念、创建方法、同步机制及实际应用。通过对多线程基础知识的介绍和具体示例的演示,希望帮助读者更好地理解和应用Java多线程编程,提高程序的效率和性能。
19 1
|
18天前
|
Java
深入理解Java中的多线程编程
本文将探讨Java多线程编程的核心概念和技术,包括线程的创建与管理、同步机制以及并发工具类的应用。我们将通过实例分析,帮助读者更好地理解和应用Java多线程编程,提高程序的性能和响应能力。
20 4
|
9天前
|
Java 数据处理 调度
Java中的多线程编程:从基础到实践
本文深入探讨了Java中多线程编程的基本概念、实现方式及其在实际项目中的应用。首先,我们将了解什么是线程以及为何需要多线程编程。接着,文章将详细介绍如何在Java中创建和管理线程,包括继承Thread类、实现Runnable接口以及使用Executor框架等方法。此外,我们还将讨论线程同步和通信的问题,如互斥锁、信号量、条件变量等。最后,通过具体的示例展示了如何在实际项目中有效地利用多线程提高程序的性能和响应能力。
|
10天前
|
安全 算法 Java
Java中的多线程编程:从基础到高级应用
本文深入探讨了Java中的多线程编程,从最基础的概念入手,逐步引导读者了解并掌握多线程开发的核心技术。无论是初学者还是有一定经验的开发者,都能从中获益。通过实例和代码示例,本文详细讲解了线程的创建与管理、同步与锁机制、线程间通信以及高级并发工具等主题。此外,还讨论了多线程编程中常见的问题及其解决方案,帮助读者编写出高效、安全的多线程应用程序。
下一篇
无影云桌面