作者:路人 | 来源:互联网 | 2022-12-20 15:52
/**
* 一,AtomicInteger 是如何实现原子操作的呢?
*
* 我们先来看一下getAndIncrement的源代码:
* public final int getAndIncrement() {
* for (;;) {
* int current = get(); // 取得AtomicInteger里存储的数值
* int next = current + 1; // 加1
* if (compareAndSet(current, next)) // 调用compareAndSet执行原子更新操作
* return current;
* }
* }
*
* 这段代码写的很巧妙:
* 1,compareAndSet方法首先判断当前值是否等于current;
* 2,如果当前值 = current ,说明AtomicInteger的值没有被其他线程修改;
* 3,如果当前值 != current,说明AtomicInteger的值被其他线程修改了,这时会再次进入循环重新比较;
*
* 注意这里的compareAndSet方法,源代码如下:
* public final boolean compareAndSet(int expect, int update) {
* return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
* }
*
* 调用Unsafe来实现
* private static final Unsafe unsafe = Unsafe.getUnsafe();
*
* 二,java提供的原子操作可以原子更新的基本类型有以下三个:
*
* 1,AtomicBoolean
* 2,AtomicInteger
* 3,AtomicLong
*
* 三,java提供的原子操作,还可以原子更新以下类型的值:
*
* 1,原子更新数组,Atomic包提供了以下几个类:AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray
* 2,原子更新引用类型,也就是更新实体类的值,比如AtomicReference
* AtomicReference:原子更新引用类型的值
* AtomicReferenceFieldUpdater:原子更新引用类型里的字段
* AtomicMarkableReference:原子更新带有标记位的引用类型
* 3,原子更新字段值
* AtomicIntegerFieldUpdater:原子更新整形的字段的更新器
* AtomicLongFieldUpdater:原子更新长整形的字段的更新器
* AtomicStampedReference:原子更新带有版本号的引用类型的更新器
*
*
*/
示例代码如下:
[java] view plain copy
- import java.util.concurrent.atomic.AtomicInteger;
- import sun.misc.Unsafe;
-
- public class TestAtomic {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public static void main(String[] args) {
-
- AtomicInteger atomicInteger = new AtomicInteger(1);
- System.out.println("--初始值atomicInteger = " + atomicInteger);
-
-
- System.out.println("atomicInteger.getAndIncrement() = " + atomicInteger.getAndIncrement());
- System.out.println("--自增后的 atomicInteger = " + atomicInteger);
-
-
- System.out.println("atomicInteger.getAndIncrement() = " + atomicInteger.decrementAndGet());
- System.out.println("--自减后的 atomicInteger = " + atomicInteger);
-
-
- System.out.println("atomicInteger.getAndIncrement() = " + atomicInteger.addAndGet(10));
- System.out.println("--自减后的 atomicInteger = " + atomicInteger);
-
-
- System.out.println("atomicInteger.getAndIncrement() = " + atomicInteger.compareAndSet(1, 2));
- System.out.println("--自减后的 atomicInteger = " + atomicInteger);
- System.out.println("atomicInteger.getAndIncrement() = " + atomicInteger.compareAndSet(11, 9999));
- System.out.println("--自减后的 atomicInteger = " + atomicInteger);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- }
-
- }
四,AtomicIntegerFieldUpdater:原子更新整形的字段的更新器
[java] view plain copy
- import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
-
- public class TestAtomicIntegerFieldUpdater {
-
-
-
-
-
-
-
- private static AtomicIntegerFieldUpdater atomicIntegerFieldUpdater
- = AtomicIntegerFieldUpdater.newUpdater(User.class, "age");
-
- public static void main(String[] args) {
-
-
- User user = new User();
- user.setUserName("yangcq");
- user.setAge(1000);
-
-
- System.out.println(atomicIntegerFieldUpdater.getAndIncrement(user));
-
- System.out.println(atomicIntegerFieldUpdater.get(user));
- }
-
-
- public static class User{
- private String userName;
- public volatile int age;
-
-
- public String getUserName() {
- return userName;
- }
- public void setUserName(String userName) {
- this.userName = userName;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- }
-
- }
五,java原子操作类在实际项目中的应用(java原子操作类的应用场景)
java原子操作类 AtomicInteger 在实际项目中的应用。HttpClientFacotryBean工厂会工作在多线程环境中,生成Httpclient,
就相当于建立HttpClient连接,通过工厂模式控制HttpClient连接,能够更好的管理HttpClient的生命周期。而我们使用java原子
操作类AtomicInteger来控制计数器,就是为了保证,在多线程的环境下,建立HttpClient连接不会出错,不会出现2个线程竞争一个
HttpClient连接的情况。
[html] view plain copy
- bean配置如下:
- <bean id="Httpclient" name="httpclient" class="com.yangcq.initBean.HttpClientFacotryBean">
- <property name="connectionManager" ref="connectionManagers" >property>
- <property name="map">
- <map>
- <entry key="http.socket.timeout" value="30000" />
- <entry key="http.connection.timeout" value="30000" />
- <entry key="http.conn-manager.timeout" value="6000" />
- map>
- property>
- bean>
[java] view plain copy
- java实现类:
- import java.io.IOException;
- import java.util.Map;
- import java.util.concurrent.atomic.AtomicInteger;
- import org.apache.http.HttpException;
- import org.apache.http.HttpRequest;
- import org.apache.http.HttpRequestInterceptor;
- import org.apache.http.client.HttpClient;
- import org.apache.http.conn.ClientConnectionManager;
- import org.apache.http.conn.params.ConnManagerPNames;
- import org.apache.http.conn.params.ConnManagerParamBean;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.params.BasicHttpParams;
- import org.apache.http.params.CoreConnectionPNames;
- import org.apache.http.params.HttpConnectionParamBean;
- import org.apache.http.params.HttpParams;
- import org.apache.http.protocol.HttpContext;
- import org.apache.log4j.Logger;
- import org.springframework.beans.factory.BeanInitializationException;
- import org.springframework.beans.factory.DisposableBean;
- import org.springframework.beans.factory.FactoryBean;
- import org.springframework.beans.factory.InitializingBean;
-
-
-
-
-
-
-
- public class HttpClientFacotryBean implements FactoryBean,InitializingBean,DisposableBean {
- private static final Logger logger = Logger.getLogger(HttpClientFacotryBean.class);
- private DefaultHttpClient httpClient;
- private ClientConnectionManager clientConnectionManager = null;
- private Map map = null;
-
- public void afterPropertiesSet() throws Exception {
- if (null == clientConnectionManager) {
- throw new BeanInitializationException("The connection manager must be set in " + this.getClass().getName() + "...");
- }
- HttpParams httpParams = new BasicHttpParams();
- if (null != map) {
- HttpConnectionParamBean httpConnectionParamBean = new HttpConnectionParamBean(httpParams);
- String connectionTimeout = (String) map.get(CoreConnectionPNames.CONNECTION_TIMEOUT);
- if (null != connectionTimeout)
- httpConnectionParamBean.setConnectionTimeout(Integer.parseInt(connectionTimeout));
- String soTimeout = (String) map.get(CoreConnectionPNames.SO_TIMEOUT);
- if (null != connectionTimeout)
- httpConnectionParamBean.setSoTimeout(Integer.parseInt(soTimeout));
- ConnManagerParamBean connManagerParamBean = new ConnManagerParamBean(httpParams);
- String timeout = (String) map.get(ConnManagerPNames.TIMEOUT);
- if (null != timeout)
- connManagerParamBean.setTimeout(Long.parseLong(timeout));
- }
- this.httpClient = new DefaultHttpClient(clientConnectionManager, httpParams);
- this.httpClient.addRequestInterceptor(new HttpRequestInterceptor() {
- public void process(final HttpRequest request,final HttpContext context) throws HttpException,IOException {
- AtomicInteger count = (AtomicInteger) context.getAttribute("count");
- if (null == count) {
- count = new AtomicInteger(1);
- context.setAttribute("count", count);
- }
- request.addHeader("Count", Integer.toString(count.getAndIncrement()));
- if (logger.isDebugEnabled()) {
- logger.debug("\n=====这是第 " + count + " 次连接=====\n");
- }
- }
- });
- }
- public void destroy() throws Exception {
- if (null != params)
- map.clear();
- if (null != clientConnectionManager)
- clientConnectionManager.closeExpiredConnections();
- }
- public ClientConnectionManager getConnectionManager() {
- return clientConnectionManager;
- }
- public Map getParams() {
- return map;
- }
- public void setConnectionManager(ClientConnectionManager clientConnectionManager) {
- this.clientConnectionManager = clientConnectionManager;
- }
- public void setParams(Map map) {
- this.map = map;
- }
- public Object getObject() throws Exception {
- return this.httpClient;
- }
- public Class getObjectType() {
- return HttpClient.class;
- }
- public boolean isSingleton() {
- return false;
- }
- }