现在我们知道数组列表没有同步和向量。但是这个同步如何使向量线程安全?显示它将使其线程安全的一个示例将非常有用
答案 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
方法可能会导致以下问题:
return elementData(index)
。这将返回null
,因为删除已使用null
覆盖该地点。因此,同步方法使Vector确实有点线程安全。但是,如果根据程序的要求需要更多线程安全性,通常需要将整个代码块与对向量(以及其他对象)的多次调用同步。