以下代码,semaphore会不会引起一些同步的问题(重入),需要修改吗

[code="java"]
package learn;
import java.util.concurrent.Semaphore;
class applePlate{
static Semaphore apple = new Semaphore(2);
static Semaphore space = new Semaphore(3);
}

class Eater implements Runnable{
String name;
Object o;
Eater(String name, Object o){
this.name = name;
this.o = o;
}
public void run(){
int count = 4;
while(count-- > 0){

            try{
                applePlate.apple.acquire();
            }catch(InterruptedException e){
                throw new RuntimeException(e);
            }
            applePlate.space.release();
            System.out.println("Eater " + name +" eat"+"   :left " 
                    + applePlate.apple.availablePermits());

    }
}

}

class Producer implements Runnable{
String name;
Object o;
Producer(String name, Object o){
this.name = name;
this.o = o;
}

public void run(){
    int count = 3;
    while(count-- > 0){

            try{
                applePlate.space.acquire();
            }catch(InterruptedException e){
                throw new RuntimeException(e);
            }
            applePlate.apple.release();
            System.out.println("Producer " + name +" produce"+"   :left " 
                    + applePlate.apple.availablePermits());

    }
}

}

class Go {
public static void main(String args[]){
Object o = new Object();
Eater e1 = new Eater("eee", o), e2 = new Eater("eee2", o);
Producer p1 = new Producer("ppp", o), p2 = new Producer("ppp2", o);
Thread th1 = new Thread(e1);
Thread th2 = new Thread(e2);
Thread th3 = new Thread(p1);
Thread th4 = new Thread(p2);
th1.start();
th2.start();
th3.start();
th4.start();
}
}
[/code]

0

2个回答

信号量只是在信号不够的时候挂起线程,但是并不能保证信号量足够的时候获取对象和返还对象是线程安全的。所以你还需要有Lock来保证并发的正确性。

0
odmedabs
odmedabs 所以用Semaphore的话尽量都用Semaphore,和线程锁混用会有麻烦的
6 年多之前 回复
odmedabs
odmedabs 个人觉得声明一个Semaphore mutex值为0,1,比较好,,如果是Lock的话可能死锁。。 比如Th1 lock.lock(); sem.acquire(); lock.unlock(),另外一个地方Th2 是lock.lock(); sem.release(); lock.unlock();注意到如果Th1先被调度,程序阻塞在sem.acquire(),并不释放lock,那么Th2不会获得lock锁,永远不会发生sem.release()
6 年多之前 回复

"并不能保证信号量足够的时候获取对象和返还对象是线程安全的" 这是哪家的Java Doc声明的?

0
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!