无参方法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也获得了许可。