您的位置:首页 > 编程语言 > Java开发

【线程】Java线程(3)-线程安全解决方案(加锁机制)Atomic && synchronized

2014-04-25 16:47 507 查看
1、通过加锁机制,限制不同线程对同一资源的访问;

1)、Atomic

在java.util.concurrent.atomic有一些具体的类,如AtomicInteger,对该类型的数据做了原子性操作。具体的实现基于CAS,CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。这个操作有可能出现ABA的问题,这里有不展开讨论了。

以在ATM机同时取现和存钱举例。

具体操作类ModifyNum.java

public class ModifyNum {
	private AtomicInteger totalNum;

	public ModifyNum(AtomicInteger totalNum) {
		super();
		this.totalNum = totalNum;
	}

	public void addNum() {
		totalNum.addAndGet(100);
		System.out.println(Thread.currentThread().getName() + "-当前数量值为:"
				+ totalNum);
	}

	public void delNum() {
		totalNum.addAndGet(-500);
		System.out.println(Thread.currentThread().getName() + "-当前数量值为:"
				+ totalNum);
	}
}
测试类Main.java

public class Main {
	public static void main(String[] args) {
		final ModifyNum modifyNum = new ModifyNum(new AtomicInteger(1000));
		new Thread("add"){
			public void run(){
				modifyNum.addNum();
			}
		}.start();
		new Thread("del"){
			public void run(){
				modifyNum.delNum();
			}
		}.start();
	}
}
可能的输出:

add-当前数量值为:1100
del-当前数量值为:600
del-当前数量值为:100
add-当前数量值为:200
del-当前数量值为:-300
add-当前数量值为:-200
del-当前数量值为:-700
add-当前数量值为:-600
del-当前数量值为:-1100
add-当前数量值为:-1000
2)、synchronized

Java中关键字,独占锁,悲观锁。可以作用的方法上,也可以作用在方法块上,保证同一时刻只能有一个线程来访问该关键字作用的代码。

以在ATM机同时取现和存钱举例。

具体操作类ModifyNum.java

public class ModifyNum {
	private int totalNum;

	public ModifyNum(int totalNum) {
		super();
		this.totalNum = totalNum;
	}

	public void addNum() {
		synchronized (this) {
			totalNum += 100;
			System.out.println(Thread.currentThread().getName() + "-当前数量值为:"
					+ totalNum);
		}
	}

	public synchronized void delNum() {
		totalNum -= 500;
		System.out.println(Thread.currentThread().getName() + "-当前数量值为:"
				+ totalNum);
	}
}
测试类Main.java

public class Main {
	public static void main(String[] args) {
		final ModifyNum modifyNum = new ModifyNum(1000);
		for (int i = 0; i < 5; i++) {
			new Thread("add"){
				public void run(){
					modifyNum.addNum();
				}
			}.start();
			new Thread("del"){
				public void run(){
					modifyNum.delNum();
				}
			}.start();
		}
	}
}
可能的输出:

add-当前数量值为:1100
del-当前数量值为:600
del-当前数量值为:100
add-当前数量值为:200
del-当前数量值为:-300
del-当前数量值为:-800
del-当前数量值为:-1300
add-当前数量值为:-1200
add-当前数量值为:-1100
add-当前数量值为:-1000
虽然线程执行顺序仍然是不固定的,但是加入synchronized限制之后,同一时刻只有一个线程访问当前代码块,使得最后的结果和预期一致。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: