使用java信号量作为两个可运行类之间的锁

使用java信号量作为两个可运行类之间的锁,java,multithreading,concurrency,mutex,semaphore,Java,Multithreading,Concurrency,Mutex,Semaphore,我有三个对象,它们是实现Runnable接口的两个不同类的实例。其中一个对象更改其他两个对象的计数器,但我希望确保整个更新操作不会被其他线程中断(即,我希望对我的关键部分使用锁) 在下面的代码中(这是实际代码的说明,而不是代码本身),我希望确保关键部分中的代码在没有任何中断的情况下执行 我的一个想法是在Worker类中定义一个二进制信号量m,并用m.acquire()和operations围绕每个涉及值和操作的操作。但是,在“Runner”类中,我调用了incrementValue(),如果我用

我有三个对象,它们是实现
Runnable
接口的两个不同类的实例。其中一个对象更改其他两个对象的计数器,但我希望确保整个更新操作不会被其他线程中断(即,我希望对我的关键部分使用锁)

在下面的代码中(这是实际代码的说明,而不是代码本身),我希望确保关键部分中的代码在没有任何中断的情况下执行

我的一个想法是在
Worker
类中定义一个二进制信号量m,并用
m.acquire()
operations
围绕每个涉及
值和
操作的操作。但是,在“Runner”类中,我调用了
incrementValue()
,如果我用
acquire()/release()
调用包围CS,而我在
incrementValue()
中调用了相同的东西,那就没有意义了

我有点困惑,我应该把我的信号灯放在哪里以实现互斥

谢谢

class Worker implements Runnable{
    int value;
    int operations;
    // Semaphore m = new Semaphore(1);
    ...
    ...
    void incrementValue(int n){
        // m.acquire() here??
        this.operations++;
        this.value += n;
        // m.release() here??
    }
    ...
    @Override
    public void run(){
        ...
        this.operations++;
        this.value = getRandomNum(); 
        ...
    }
}

class Runner implements Runnable {
    Worker a, b;
    ...
    ...
    @Override
    public void run(){
        ...
        // Start of the CS
        // a.m.acquire() here?
        // b.m.acquire() here?
        a.incrementValue(x);
        System.out.println("Value in WorkerA incremented by " + x);
        b.incrementValue(y);
        System.out.println("Value in WorkerB incremented by " + y);
        // a.m.release() here?
        // b.m.release() here?
        // end of the CS
        ...
    }
    ...
}

听起来你面临的问题和你要解决的问题是一样的
ReentrantLock
允许您执行以下操作:

final ReentrantLock m = new ReentrantLock();

void foo() {
    m.lock();
    doFooStuff();
    m.unlock();
}

void bar() {
    m.lock();
    foo();
    doAdditionalBarStuff();
    m.unlock();
}
lock()
调用检查调用线程是否已经拥有锁。如果调用者没有,那么它首先获取锁,在必要时等待,最后在返回之前将
count
变量设置为1

来自同一线程的后续
lock()
调用将看到该线程已经拥有锁,它们将简单地增加计数器并返回


unlock()
调用递减计数器,并且只有当计数达到零时才释放锁。

我才意识到
incrementValue()
只由
运行程序
线程调用,其他什么都不调用。因此,我假设在
incrementValue()
中不使用
acquire()/release()
应该是可以的-它只使用一个线程(只有一个
Runner
线程和两个
Worker
线程)。只要我在
Runner.run()
Worker.run()
的内部有
acquire()/release()
,这是修改
int
变量的另一种方法,我就可以了。对吗?Re,“
incrementValue()
仅由
运行程序
线程调用…”锁定的目的不是阻止多个线程同时使用同一方法。目的是防止他们同时访问相同的数据。如果
incrementValue()
对其他线程使用的同一变量进行操作,则必须使用锁。谢谢。对
int
变量的修改发生在不同线程使用的不同方法中。然后,我假设我必须通过对每个试图修改变量的方法使用相同的锁来控制对这些变量的访问。i、 e.围绕对这些变量的所有写入的
m.lock()/m.unlock()
。对吧?对。访问相同共享数据的所有线程都应该锁定相同的共享锁。