java进阶:15.4 多线程 - 信号量、原子操作

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/L20902/article/details/89318850

1. 信号量

计算机科学中,信号量指对共同资源进行访问控制的对象。在访问资源之前,线程必须从信号量获取许可。在访问完资源之后,这个线程必须将许可返回给信号量。

为了创建信号量,必须确定许可的数量,同时可选用公平策略。任务通过调用信号量的acquire() 方法来获得许可,通过调用信号量的release()方法来释放许可。一旦获得许可, 信号量中可用许可的总数减1。一旦许可被释放,信号量中可用许可的总数加1。

	private static Semaphore = new Semaphore(1);
	...
	public void deposit(int amount){
		try{
		     semaphore.acquire();
		     ...
		 }
		 catch(InterruptedException ex){
		 }

		finally{
			semaphore.release();
		}

2. 原子操作

所谓的原子性操作即 不可中断的操作,比如赋值操作 int i = 5;

原子性操作本身是线程安全的,但是 i++ 这个行为,事实上是有3个原子性操作组成的。
步骤 1. 取 i 的值
步骤 2. i + 1
步骤 3. 把新的值赋予i
这三个步骤,每一步都是一个原子操作,但是合在一起,就不是原子操作。就不是线程安全的。

换句话说,一个线程在步骤1 取 i 的值结束后,还没有来得及进行步骤2,另一个线程也可以取 i 的值了。

i++ ,i–, i = i+1 这些都是非原子性操作。
只有int i = 1,这个赋值操作是原子性的。

3. AtomicInteger

JDK6 以后,新增加了一个包 java.util.concurrent.atomic,里面有各种原子类,比如 AtomicInteger

AtomicInteger 提供了各种自增,自减等方法,这些方法都是原子性的。 换句话说,自增方法 incrementAndGet 是线程安全的,同一个时间,只有一个线程可以调用这个方法。

import java.util.concurrent.atomic.AtomicInteger;
public class TestThread {
    public static void main(String[] args) throws InterruptedException {
    	AtomicInteger atomicI =new AtomicInteger();
    	int i = atomicI.decrementAndGet();
    	int j = atomicI.incrementAndGet();
    	int k = atomicI.addAndGet(3); 	
    }  
}

猜你喜欢

转载自blog.csdn.net/L20902/article/details/89318850