synchronized Atomic

Atomic译为原子的,顾名思义,肯定跟线程安全有关系。

之前做项目遇到多个线程公用同一资源的问题,当时用的是synchronized。

如果不考虑线程安全,那么多个线程公用的资源,会相互干扰。

例如:

public class Try {
	private static int count;

	public static void main(String[] args) {
		for (int i = 0; i < 1000; i++) {

			new Thread(new Runnable() {

				public void run() {
					Try.fun();
				}
			}).start();
		}
		System.out.println("count:" + count);
	}

	public static void fun() {
		try {
			TimeUnit.MILLISECONDS.sleep(5);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		count++;
	}
}
由于线程不安全,最后输出count随机数字。这是由于count在内存中只有一份拷贝,在count还没有自加之前又被取走了。因此结果小于1000。


如果加上synchronized又会是怎样的结果呢。

public class Try {
	private static int count;

	public static void main(String[] args) {
		for (int i = 0; i < 1000; i++) {

			new Thread(new Runnable() {

				public void run() {
					Try.fun();
				}
			}).start();
		}
		System.out.println("count:" + count);
	}

	public static void fun() {
		try {
			TimeUnit.MILLISECONDS.sleep(5);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		synchronized (Try.class) {
			count++;
		}
	}
}
最后的结果还是小于1000,TimeUnit.MILLISECONDS.sleep(5);睡眠了5毫秒。在所有的线程还没有完全执行完就打印出了结果。

又需要介绍CountDownLatch,他是一个计数器,可以等待倒数到0再执行下面的操作。

public class Try {
	private static int count;

	public static void main(String[] args) {
		final CountDownLatch latch = new CountDownLatch(1000);
		for (int i = 0; i < 1000; i++) {

			new Thread(new Runnable() {

				public void run() {
					Try.fun();
					latch.countDown();
				}
			}).start();
		}
		try {
			latch.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("count:" + count);
	}

	public static void fun() {
		try {
			TimeUnit.MILLISECONDS.sleep(5);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		synchronized (Try.class) {
			count++;
		}
	}
}
现在到这一步,结果就绝对不会有错了,必然是1000。

然而除了synchronized,还有一种轻量级的原子操作。AtomicXxx。这个已经封装好,当他取值或者改变值得时候都是原子操作。

它包含有:

AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference
AtomicIntegerArray,AtomicLongArray
AtomicLongFieldUpdater,AtomicIntegerFieldUpdater,AtomicReferenceFieldUpdater
AtomicMarkableReference,AtomicStampedReference,AtomicReferenceArray

还是上面那个例子:

public class Try {
	private static AtomicInteger count = new AtomicInteger(0);

	public static void main(String[] args) {
		final CountDownLatch latch = new CountDownLatch(1000);
		for (int i = 0; i < 1000; i++) {

			new Thread(new Runnable() {

				public void run() {
					Try.fun();
					latch.countDown();
				}
			}).start();
		}
		try {
			latch.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("count:" + count);
	}

	public static void fun() {
		try {
			TimeUnit.MILLISECONDS.sleep(5);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		count.getAndIncrement();
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值