我应该使用lock.lock():在这个方法?

时间:2012-06-09 16:35:26

标签: java

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

这一事实

特定代码块

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

这座桥可供一定数量的汽车使用(容量有限),而且只有一种方式。

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();或者这只是胡说八道?

提前致谢

3 个答案:

答案 0 :(得分:2)

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

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

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

但是由于锁定有成本,您也可以将变量封装在AtomicLong

答案 1 :(得分:0)

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

我还认为你在调用方法中使用semaphore作为守护锁。

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

答案 2 :(得分:0)

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

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

这称为丢失更新问题。