0

我编写了这个方法,其目的是通知线程正在离开

特定的代码块

线程代表正在离开桥梁的汽车,以便其他汽车可以穿过它。

给定数量的汽车(容量有限)可以进入这座桥,而且只有一种方式。

public void getout(int diection){
        // release the lock
        semaphore.release();

        try{
            lock.lock(); //access to shared data
            if(direction == Car.NORTH)
                nNordTraversing--; //decreasing traversing threads
            else
                nSudTraversing--;

            bridgeCond.signal(); 

        }finally{
            lock.unlock();
        }

    }

我的问题是:我应该使用 lock.lock(); 或者这只是胡说八道?

提前致谢

4

3 回答 3

2

由于我们没有完整的代码(信号量是什么?),这个答案部分基于猜测。

如果您的问题与递增和递减操作有关,那么您应该知道这些操作实际上不是原子的。

所以是的,如果您有其他线程访问这些变量,您需要保护它们以确保没有其他线程可以读取它们或更糟的是尝试执行相同的操作,因为两个并行增量可能只导致一个有效。

但由于锁定是有代价的,您也可以将变量封装在AtomicLong中。

于 2012-06-09T16:39:10.633 回答
0

好吧,我假设 nNordTraversing 和 nSudTraversing 是共享数据。由于 ++ 和 -- 不是原子操作,因此在更改之前锁定它们是有意义的。否则可能会发生以下情况:

  • 您读取了变量 nNordTraversing(例如 7)
  • 另一个线程被调度并完成了它的 getout 方法,它改变了变量(例如 7 -- --> 6)
  • 您被安排回来,更改变量,但在其他线程更改之前读取的旧数据(例如 7 --> 8)
  • 另一个线程的更改被覆盖,计数不再一致(例如,现在是 8,但应该是 7)

这称为丢失更新问题。

于 2012-06-09T16:46:01.037 回答
0

从代码片段和需求getout不会被模拟线程调用,只有队列前面的线程,因此调用的方法getout应该同步,因为并非所有线程(汽车)都可以在队列的前面.

我还认为您semaphore在调用方法中用作保护锁。

如果在您的实现getout中被多个方法调用,那么是的,您需要同步并且您的代码是正确的。

于 2012-06-09T16:42:21.967 回答