Semaphore的使用之方法tryAcquire()的使用

无参方法tryAcquire()的作用是尝试的获得1个许可,如果获取不到则返回false,该方法通常与if语句结合使用,其具有无阻塞的特点。无阻塞的特点可以使线程不至于在同步处一直持续等待的状态,如果if语句判断不成立则线程会继续走slse语句,程序会继续向下运行。

创建Java项目Semaphore_tryAcquire,MyService.java代码如下:

package com.yc.semephore_3;

import java.util.concurrent.Semaphore;

public class MyService {
	private Semaphore semaphore = new Semaphore(1);
	
	@SuppressWarnings("unused")
	public void testFair(){
			if(semaphore.tryAcquire()){
				System.out.println( Thread.currentThread().getName() + "首先进入");
				//做一些耗时操作
				for(int i = 0; i < Integer.MAX_VALUE ; i ++){
					String newString = new String();
				}
				
				semaphore.release();
			}else{
				System.out.println(Thread.currentThread().getName() + "没有得到许可");
			}
	}
}
创建ThreadA和ThreadB如下:
package com.yc.semephore_3;

public class ThreadA extends Thread{
	private MyService service;
	
	public ThreadA(MyService service){
		super();
		this.service = service;
	}
	
	@Override
	public void run() {
		service.testFair();
	}

}

package com.yc.semephore_3;

public class ThreadB extends Thread{
	private MyService service;
	
	public ThreadB(MyService service){
		super();
		this.service = service;
	}
	
	@Override
	public void run() {
		service.testFair();
	}

}
创建SemaphoreTryAcquireTest.java如下:

package com.yc.semephore_3;

public class SemaphoreTryAcquireTest {
	public static void main(String[] args) {
		MyService service = new MyService();
		
		ThreadA a = new ThreadA(service);
		a.setName("A");
		
		ThreadB b = new ThreadB(service);
		b.setName("B");	
		
		a.start();
		b.start();
	}
}

测试结果如下:

A首先进入
B没有得到许可

若把Semaphore的初始化permits参数改成2,测试结果如下:
B首先进入
A首先进入

这也正符合前面的两个许可两个线程竞争。


有参方法tryAcquire(permits)的作用是尝试获取x个许可,如果获取不到则返回false,把上面的Service.java修改如下:
package com.yc.semephore_3;

import java.util.concurrent.Semaphore;

public class MyService {
	private Semaphore semaphore = new Semaphore(3);
	
	@SuppressWarnings("unused")
	public void testFair(){
			if(semaphore.tryAcquire(3)){
				System.out.println( Thread.currentThread().getName() + "首先进入");
				//做一些耗时操作
				for(int i = 0; i < Integer.MAX_VALUE ; i ++){
					String newString = new String();
				}
				
				semaphore.release();
			}else{
				System.out.println(Thread.currentThread().getName() + "没有得到许可");
			}
	}
}

得到如下测试结果:

A首先进入
B没有得到许可

倘若把
private Semaphore semaphore = new Semaphore(3);
改成
private Semaphore semaphore = new Semaphore(2);
测试结果如下:
A没有得到许可
B没有得到许可

说明2个不够。



有参方法tryAcquire(long timeout, TimeUnit unit)的作用是在指定的时间内尝试地获取1个许可,如果获取不到就返回false。

将Service.java修改如下:

package com.yc.semephore_3;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class MyService {
	private Semaphore semaphore = new Semaphore(1);
	
	@SuppressWarnings("unused")
	public void testFair(){
			try {
				if(semaphore.tryAcquire(3, TimeUnit.SECONDS)){
					System.out.println( Thread.currentThread().getName() + "首先进入");
					//做一些耗时操作
					for(int i = 0; i < Integer.MAX_VALUE ; i ++){
						String newString = new String();
					}
					semaphore.release();
				}else{
					System.out.println(Thread.currentThread().getName() + "没有得到许可");
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
	}
}
3 秒后测试结果如下:

A首先进入
B没有得到许可

倘若将程序里面的耗时操作改成低于三秒后,我把条件改成 i  <   Integer.MIN_VALUE 测试的结果为:
A首先进入
B首先进入

与上面的结果对比知道当线程A进入if后用掉1个许可,耗时操作后,release许可,此时耗时并未超过3秒,所以线程B也获得了许可。

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值