每天一例多线程[day8]-----AutomicInteger原子操作

即使我们使用volitile,也无法保证多线程访问共享变量的原子性,如下:

 
 
package com.jeff.base.sync007;

/**
 *
 * volatile关键字不具备synchronized关键字的原子性(同步)
 * @author jeff
 *
 */
public class VolatileNoAtomic extends Thread{
	private static volatile int count;
	//private static AtomicInteger count = new AtomicInteger(0);
	
	private static void addCount(){
		for (int i = 0; i < 1000; i++) {
			count++ ;
			//count.incrementAndGet();
		}
		System.out.println(count);
	}
	
	public void run(){
		addCount();
	}
	
	public static void main(String[] args) {
		
		VolatileNoAtomic[] arr = new VolatileNoAtomic[100];
		for (int i = 0; i < 10; i++) {
			arr[i] = new VolatileNoAtomic();
		}
		
		for (int i = 0; i < 10; i++) {
			arr[i].start();
		}
	}
		
}

启动10个线程,对volitile修饰的count静态变量进行+1,最后的结果并不是10000,说明volitile并不保证同步,也就是无法原子性。

打印结果:

1048
1048
3012
4012
4048
5048
6048
7048
8595
9036

所以我们可以使用AutomicInteger来解决这个问题:

package com.jeff.base.sync007;

import java.util.concurrent.atomic.AtomicInteger;

/**
 *
 * volatile关键字不具备synchronized关键字的原子性(同步)
 * @author jeff
 *
 */
public class VolatileNoAtomic extends Thread{
	//private static volatile int count;
	private static AtomicInteger count = new AtomicInteger(0);
	
	private static void addCount(){
		for (int i = 0; i < 1000; i++) {
			//count++ ;
			count.incrementAndGet();
		}
		System.out.println(count);
	}
	
	public void run(){
		addCount();
	}
	
	public static void main(String[] args) {

		VolatileNoAtomic[] arr = new VolatileNoAtomic[100];
		for (int i = 0; i < 10; i++) {
			arr[i] = new VolatileNoAtomic();
		}
		
		for (int i = 0; i < 10; i++) {
			arr[i].start();
		}
	}
	
	
	
	
}

打印结果,最终得到10000:

1927
2000
3000
4090
5000
6391
7000
9018
9113
10000


多个addAndGet在一个自定义的方法内部是非原子的,需要同步对象锁修饰:

package com.jeff.base.sync007;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * //多个addAndGet在一个方法内是非原子性的,需要加synchronized进行修饰,
 * 保证4个addAndGet整体原子性
 * @author jeffSheng
 *
 */
public class AtomicUse {

	private static AtomicInteger count = new AtomicInteger(0);
	
	/**synchronized*/
	public synchronized int multiAdd(){
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			count.addAndGet(1);
			count.addAndGet(2);
			count.addAndGet(3);
			count.addAndGet(4); //+10
			return count.get();
	}
	
	
	public static void main(String[] args) {
		
		final AtomicUse au = new AtomicUse();

		List<Thread> ts = new ArrayList<Thread>();
		for (int i = 0; i < 100; i++) {
			ts.add(new Thread(new Runnable() {
				@Override
				public void run() {
					System.out.println(au.multiAdd());
				}
			}));
		}

		for(Thread t : ts){
			t.start();
		}


	
		

		
	}
}


猜你喜欢

转载自blog.csdn.net/shengqianfeng/article/details/80559230
今日推荐