java Atomic原子性

package com.huateng.atomic;

import java.util.concurrent.atomic.AtomicInteger;
/**
 * 普通的不加锁情况,increment方法内分两个步骤,get value和value+1
 * 期望的流程是:线程1走完value+1后线程2开始get value
 * 当发生线程1已经get value且没有value+1时线程2开始get value,这个值就比期望值少1
 * synchronize意思是强制线程1走完value+1才允许线程2开始
 * 
 * Atomic的区别在:普通的int类型为每个线程分配工作区间,线程1的set value+1必定是操作线程1的get value
 * 		而AtomicInteger当线程1在get value和set value之间别的线程也做了set value
 * 		则compareAndSet会发现本线程1的value值已被其他线程改变
 * 		从而重新get value,这时get的值是线程2改变过的新值了
 * 意思是get和set之间不会被其他线程干扰,所以被称作原子性
 * 		
 * @author huateng
 *
 */
public class Increment4 extends Thread{
	private Counter2 counter;
	public Increment4(Counter2 counter){
		this.counter = counter;
	}
	public void run(){
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		counter.increment();
	}
	public static void main(String[] args) throws Exception{
		int size = 10000;
		long start = System.currentTimeMillis();
		Counter2 counter = new Counter2();
//		for(int i=0;i<10000;i++){
//			new Increment4(counter).start();
//		}
//		Thread.sleep(5888);
		Thread[] threads1 = new Thread[size];
		/**
		 * 这里用for(Thread t:threads1)不能向数组里面赋值,调用时空指针
		 */
//		for(Thread t:threads1){
//			t = new Increment4(counter);
			t.start();
//			System.out.println("t: "+t);
//		}
		for(int i=0;i<size;i++){
			threads1[i] = new Increment4(counter);
		}
		for(Thread t:threads1){
			t.start();
		}
		for(Thread t:threads1){
			t.join();
		}
		System.out.println("counter: "+counter.getValue());
		long end = System.currentTimeMillis();
		System.out.println("Atomic cost time: "+(end-start));
		
		Counter3 counter3 = new Counter3();
//		for(int i=0;i<10000;i++){
//			new Increment5(counter3).start();
//		}
//		Thread.sleep(5888);
		Thread[] threads2 = new Thread[size];
//		for(Thread t:threads2){
//			t = new Increment5(counter3);
			t.start();
//		}
		for(int i=0;i<size;i++){
			threads2[i] = new Increment5(counter3);
		}
		for(Thread t:threads2){
			t.start();
		}
		for(Thread t:threads2){
			t.join();
		}
		System.out.println("counter3: "+counter3.getValue());
		long end2 = System.currentTimeMillis();
		System.out.println("synchronized cost time: "+(end2-end));
	}
}
class Increment5 extends Thread{
	private Counter3 counter3;
	public Increment5(Counter3 counter3) {
		this.counter3 = counter3;
	}
	public void run(){
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		counter3.increment();
	}
}
class Counter2{
	private AtomicInteger value = new AtomicInteger(0);
	public AtomicInteger getValue() {
		return value;
	}
	public void setValue(AtomicInteger value) {
		this.value = value;
	}
	public void increment(){
		value.incrementAndGet();//跟下面for循环写法一样
//		for(;;){
//			int current = value.get();
//			int next = current + 1;
//			if(value.compareAndSet(current, next)){
//				return ;
//			}
//		}
	}
}
class Counter3{
	private int value = 0;
	public int getValue() {
		return value;
	}
	public void setValue(int value) {
		this.value = value;
	}
	public synchronized void increment(){
		++value;
	}
}
//counter: 10000
//Atomic cost time: 2448
//counter3: 10000
//synchronized cost time: 2377


join方法意思是等待线程完成,如果改成Thread.sleep(5555)也会得到正确值。不然,main线程走到print语句时,10000个线程的加法会有一些还没有完成,得到的值将<10000

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值