我有一个线程,它只在独占访问2个信号量时才执行操作。
public void run(){
boolean a1=false;
boolean a2=false;
boolean a3=false;
while(true){
try{
if(res[1].tryAcquire()==true){
a1=true;
if((res[2].tryAcquire()==true){
a2=true;
if(res[3].tryAcquire()==true)){
a3=true;
System.out.println("Rolled the tobacco");
}
}
}
}
finally{
if(a1){
a1=false;
res[1].release();
}
if(a2){
a2=false;
res[2].release();
}
if(a3){
a3=false;
res[3].release();
}
}
}
}
}有没有一种更好的方法来写这段代码,以确保我们不会打乱获取的信号量计数?有没有办法检查当前线程是否获取了信号量?
发布于 2013-01-09 15:21:17
在Java7中,可以尝试使用Closeable。当然,肯定有更好的解决方案。
public class Region implements Closeable {
private final Semaphore semaphore;
public Region(Semaphore semaphore) {
this.semaphore = semaphore;
if (!semaphore.tryAcquire()) {
throw NotAcquiredException(semaphore);
}
}
@Override
public void close() {
semaphore.release();
}
}
public class NotAcquiredException extends Exception { ... }用法:
public void run() {
boolean a1 = false;
boolean a2 = false;
boolean a3 = false;
while (true) {
try (Closeable r1 = new Region(res[1])) {
a1 = true;
try (Closeable r2 = new Region(res[2])) {
a2 = true;
try (Closeable r3 = new Region(res[3])) {
a3 = true;
System.out.println("Rolled the tobacco");
} catch (IOException e) {
}
} catch (IOException e) {
}
} catch (IOException e) {
}
}发布于 2013-01-09 15:41:15
您可以将每个获取分离到一个try...finally中,而不是更短,但去掉了一些变量,并使每个锁应该发生的事情变得相当明显。(我将数组改为从零开始)
public void run(){
while(true){
if(res[0].tryAcquire()){
try {
if(res[1].tryAcquire()) {
try {
if(res[2].tryAcquire()){
try {
System.out.println("Rolled the tobacco");
} finally {
res[3].release();
}
}
} finally {
res[2].release();
}
}
} finally{
res[1].release();
}
}
}
}如果您需要获取大量的锁,或者在多个地方执行此操作,那么一个helper类可能会更好。至少隐藏了获取和释放信号量的样板代码。
public void run() {
SemaphoreHelper semaphoreHelper = new SemaphoreHelper(res);
while (true) {
try {
if (semaphoreHelper.aquireAll()) {
System.out.println("Rolled the tobacco");
}
} finally {
semaphoreHelper.releaseAquired();
}
}
}
private static class SemaphoreHelper {
private final Semaphore[] semaphores;
private int semaphoreIndex;
public SemaphoreHelper(Semaphore[] semaphores) {
this.semaphores = semaphores;
}
public void releaseAquired() {
while (semaphoreIndex > 0) {
semaphoreIndex--;
semaphores[semaphoreIndex].release();
}
}
public boolean aquireAll() {
while (semaphoreIndex < semaphores.length) {
if (!semaphores[semaphoreIndex].tryAcquire()) {
return false;
}
semaphoreIndex++;
}
return true;
}
}https://stackoverflow.com/questions/14229858
复制相似问题