Synchronizing make vector是如何安全的?

时间:2014-03-22 06:18:41

标签: java vector arraylist

现在我们知道数组列表没有同步和向量。但是这个同步如何使向量线程安全?显示它将使其线程安全的一个示例将非常有用

3 个答案:

答案 0 :(得分:1)

为简单起见,我们假设以下是在数组中插入元素的代码。

void insert(int element)
{
    elements[this.length] = element;
    this.length++;
}

现在假设我们有两个尝试在数组中插入元素的线程。

thread1.insert(5);
thread2.insert(7);

考虑上面的方法是不同步的。因此,以下场景将搞乱阵列的内容。

Array contents = [1,2,3,4] and length = 4

假设,thread1执行方法的第一个语句,执行转移到第二个线程。现在数组内容变为

Array contents = [1,2,3,4,5] but length is still 4

现在thread2完全执行insert

Array contents = [1,2,3,4,7] and length = 5 *Error*

现在thread1完成了方法,现在最后的内容是

Array contents = [1,2,3,4,7] and length = 6

但是如果将insert方法定义为同步,则同一对象上的两个同步方法不能一起运行。因此,当thread2调用insert时,它会发现thread1有一个锁,它将等待thread1完成。因此,您最终不会得到过时的数据。

如果synchronized始终是安全的,为什么我们甚至使用不同步的方法?

原因是,JVM上有额外的开销来锁定和解锁对象。因此,在这里使用非同步方法的权衡是你的处理时间变得更好。

如果你看一下Vector.java源代码,你会发现所有重要的方法都被定义为同步。因此,使他们线程安全。

答案 1 :(得分:0)

如果你没有“同步”,你可能面临的一个常见和令人沮丧的问题是竞争条件(调试的真正痛苦!) 更多详情:What is a race condition?

这是解释“synchronized”关键字在java中的作用的另一个线程。 我认为这个帖子中的答案解释得非常好,比我自己更好: What does 'synchronized' mean?

答案 2 :(得分:0)

正如您所知,synchronized关键字确保只有一个线程可以输入这样一个受保护的代码片段,因为只有一个线程可以保存该对象的监视器。

另一方面,线程安全是一种更复杂的机制。它通常涵盖多个对象。

但回到Vector。没有同步get方法可能会导致以下问题:

  1. 线程A使用索引等于元素计数进入get方法。 if条件被检查并证明是可以的。没有例外。
  2. 此时线程B获得处理器时间。线程A设置为等待状态。线程B进入完全运行的remove方法。现在删除一个元素,元素计数减1。
  3. 现在,线程A再次获得处理器时间并继续使用行return elementData(index)。这将返回null,因为删除已使用null覆盖该地点。
  4. 因此,同步方法使Vector确实有点线程安全。但是,如果根据程序的要求需要更多线程安全性,通常需要将整个代码块与对向量(以及其他对象)的多次调用同步。