`
wb284551926
  • 浏览: 539298 次
文章分类
社区版块
存档分类
最新评论

线程安全的AtomicLong使用

阅读更多

看一个计数的类:

[java] view plain copy
 
  1.   
[java] view plain copy
 
  1. public class Counter {  
  2.     private static long counter = 0;  
  3.     public static long addOne(){  
  4.         return ++counter;  
  5.     }  
  6. }  

 

 

初看感觉没啥问题,但这个类在多线程的环境下就会有问题了。

假如开多个线程都来使用这个计数类,它会表现的“不稳定”

 

 

[java] view plain copy
 
  1. public static void main(String[] args) {  
  2.     for(int i=0;i<100;i++){  
  3.         Thread thread = new Thread(){  
  4.             @Override  
  5.             public void run() {  
  6.                 try {  
  7.                     Thread.sleep(100);  
  8.                     if(Counter.addOne() == 100){  
  9.                         System.out.println("counter = 100");  
  10.                     }  
  11.                 } catch (InterruptedException e) {  
  12.                     e.printStackTrace();  
  13.                 }  
  14.             }  
  15.         };  
  16.         thread.start();  
  17.     }  
  18. }  


程序会开100个线程,每个线程都会把counter 加一。那么应该有一个线程拿到counter =100的值,但实际运行情况是大多数据情况下拿不到100,在少数情况能拿到100.

 

因为 Counter 类在 addOne()方法被调用时,并不能保证线程的安全,即它不是原子级别的运行性,而是分多个步骤的,打个比方:

线程1首先取到counter 值,比如为10,然后它准备加1,这时候被线程2占用了cpu,它取到counter为10,然后加了1,得到了11。这时线程1 又拿到了CPU资源,继续它的步骤,加1为11,然后也得到了11。这就有问题了。

那么怎么解决它呢?JDK在concurrent包里提供了一些线程安全的基本数据类型的实现,比如 Long型对应的concurrent包的类是AtomicLong。

现在修改下代码:

 

[java] view plain copy
 
  1. import java.util.concurrent.atomic.AtomicLong;  
  2.   
  3.   
  4. public class Counter {  
  5.     private static AtomicLong counter = new AtomicLong(0);  
  6.   
  7.   
  8.     public static long addOne() {  
  9.         return counter.incrementAndGet();  
  10.     }  
  11. }  



 

运行了多次,结果都是能输出counter = 100。

 

所以在多线程环境下,可以简单使用AtomicXXX 使代码变得线程安全。

转载请注明出处:http://blog.csdn.net/yaqingwa/article/details/17737771

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics