Java中原子操作类原则

来源:互联网 发布:网络言情小说典藏版 编辑:程序博客网 时间:2024/04/28 17:33
 java.util.concurrent.atomic 包中包括了原子变量( atomic variable )类,这些类用来实现数字和对象引用的原子状态的转换,把long类型的计数器替换成AtomicLong类型的,我们可以确保所有访问计数器状态的操作都是原子的,计数器是线程安全的了,而计数器的状态就是servlet的状态,所以我们的servlet再次车归纳为线程安全的了。

 

 

使用java.util.concurrent包中支持多线程的数据结构类(如:ConcurrentHashMap等),对写多线程JAVA程序带来很多方便.其中:java.util.concurrent.atomic包是提供原子操作的基本类.如:AtomicLong类.为了提高性能,AtomicLong等类在实现同步时,没有用synchronized关键字,而是直接使用了最低层(本地c语言实现代码)来完成的,因而你是看不到用synchronized关键字的.
比如:AtomicLong类中原子操作方法:
public final boolean compareAndSet(long expect, long update) ;
就是直接使用SUN公司低层本地代码的原子方法(native方法):
public final native boolean compareAndSwapLong(...)
来实现的.

    

 

如下面的Servlet的非安全线程的:

Java代码  收藏代码
  1. package com.etrip.web;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5.   
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.http.HttpServlet;  
  8. import javax.servlet.http.HttpServletRequest;  
  9. import javax.servlet.http.HttpServletResponse;  
  10.   
  11. /** 
  12.  * Servlet implementation class CountServlets 
  13.  */  
  14. public class CountServlets extends HttpServlet {  
  15.     private static final long serialVersionUID = 1L;  
  16.       
  17.     //记录访问此Servlet的数量  
  18.     private  static long count=0;  
  19.       
  20.       
  21.     /** 
  22.      * @see HttpServlet#HttpServlet() 
  23.      */  
  24.     public CountServlets() {  
  25.         super();  
  26.         // TODO Auto-generated constructor stub  
  27.     }  
  28.   
  29.     /** 
  30.      * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response) 
  31.      */  
  32.     @Override  
  33.     protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  34.         PrintWriter pw=response.getWriter();  
  35.         count++;  
  36.         pw.print("当前的请求次数为为:"+count);  
  37.         pw.flush();  
  38.         pw.close();  
  39.     }  
  40.   
  41.   
  42. }  

 

 

        利用像AtomicLong这样已有的线程安全对象管理类的状态是非常实用的,相对于非线程安全对象,判断一个线程安全对象的可能状态和状态的转换要容易的多了,这简化了维护和验证 线程安全性的工作。

 

 

Java代码  收藏代码
  1. package com.etrip.web;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5. import java.util.concurrent.atomic.AtomicLong;  
  6.   
  7. import javax.servlet.ServletException;  
  8. import javax.servlet.http.HttpServlet;  
  9. import javax.servlet.http.HttpServletRequest;  
  10. import javax.servlet.http.HttpServletResponse;  
  11. import java.util.concurrent.atomic.*;  
  12. /** 
  13.  *  
  14.  *  
  15.  *  
  16.  */  
  17. public class CountExtServlet extends HttpServlet {  
  18.     private static final long serialVersionUID = 1L;  
  19.       
  20.     //记录访问此Servlet的数量  
  21.     private  final AtomicLong count=new AtomicLong(0);  
  22.       
  23.     /** 
  24.      * @see HttpServlet#HttpServlet() 
  25.      */  
  26.     public CountExtServlet() {  
  27.         super();  
  28.         // TODO Auto-generated constructor stub  
  29.     }  
  30.   
  31.     /** 
  32.      * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response) 
  33.      */  
  34.     @Override  
  35.     protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  36.         PrintWriter pw=response.getWriter();  
  37.         count.incrementAndGet();  
  38.         pw.print("当前的请求次数为为:"+count.get());  
  39.         pw.flush();  
  40.         pw.close();  
  41.     }  
  42.   
  43.   
  44. }  

 

 

 

Java中提供的原子操作类

          AtomicIntegerAtomicBooleanAtomicLongAtomicReference等。这是由硬件提供原子操作指令实现的。在非激烈竞争的情况下,开销更小,速度更快。

 

        为了确保线程的全权,“检查再运行”操作(如惰性初始化)和读改写操作(如自增)必须是原子操作。
我们将“检查再运行” 和读改写操作的全部执行过程看作是符合操作。为了保证线程安全,操作必须原子
地执行。

来自:http://topmanopensource.iteye.com/blog/1735978

0 0