使用同步块锁定

时间:2017-03-02 10:33:30

标签: java arrays multithreading synchronization

  1. 如果我有变量Integer[] arr = new Integer[5]并且我使用其中一个单元作为同步块锁定 - 我可以在块中使用它吗?

    synchronize(arr[index])
    {
        arr[index]++;
    }
    
  2. 如果答案是肯定的 - 锁定究竟意味着什么?同步时程序对此锁的作用是什么?

  3. 另一个问题 - 它是仅锁定单元格还是所有数组?

    1. 换句话说 - 另一个线程是否可以并行使用块中的arr[index+1]
    2. 谢谢!

2 个答案:

答案 0 :(得分:1)

  

1)....我可以在街区内使用它吗?

  

2)如果答案是肯定的 - 锁定究竟意味着什么?程序在同步时对此锁定做了什么?

这意味着尝试在同一个对象上同步的其他一些线程将被阻止,直到"此代码"释放对象上的锁。

还有记忆一致性效应。如果您同步(正确),一个线程可以保证看到另一个线程所做的更改。

  

3)另一个问题 - 它只锁定单元格还是所有数组?

都不是。它锁定数组单元引用的对象(Integer实例)。

此外,锁定仅将 应用于尝试在同一对象上同步的其他线程。如果另一个线程尝试在另一个对象上进行同步,或者它尝试访问对象而不进行同步,则不会阻止它。

  

4)换句话说 - 另一个线程可以并行使用块中的arr [index + 1]吗?

这取决于正好其他线程的作用。见上文。

旁白:你的例子很奇怪。 Integer对象是不可变的,因此在同步上似乎没什么意义。这可能只是一个人为的例子,但如果没有,那么你很可能在应用程序设计中遇到问题。不幸的是,这个例子没有提供任何线索来理解你真正想要做的事情。

但简单的教训是:

  • 您同步对象,而不是数组元素或变量
  • 同步仅在使用共享对象时所有线程同步时才有效。

答案 1 :(得分:0)

它锁定碰巧位于同步块开头的数组中位置索引处的对象(Integer)。这在Integers的情况下不是很有用,因为语句arr [index] ++将用另一个(未锁定的)替换该对象。

更新

它不会锁定任何有用的东西,既不是完整的数组,也不是位置索引处的单元格。此外,Integer对象(不可变的)可以保存在缓存中,以便作为valueOf()的结果重用。如果未初始化数组,您可能还会收到NullPointerException。 总结:不要那样做。