2015-05-11 44 views
0

这与我之前的问题类似,因为我仍然不清楚synchronized关键字。同步性能

这次我会把它缩短。

private int count = 0; 

synchronized void increment() { 
    count++; 
} 

count是一个实例变量,它在2个线程中共享。

如果线程T1和T2试图增量次数和OS给T1机会增加数第一: -

T1采用了锁,原子递增计数,花时间增量次数是1分钟(考虑)包括时间来获得锁。

但是线程t2呢,它必须等到锁定释放。 锁定释放后,t2现在增加原子计数,这也需要1分钟。

所以同步给出的正确性,但它也需要时间来执行。线程是为了在较少的时间内完成工作,所以为什么要在线程中使用同步它有什么用处。

我的理解是否正确?

+0

你有固定的原子性,但没有知名度'count'应该是'volatile' –

+1

它的喜欢,你可以使用更多的人来完成在较短的时间了一些工作,但也有少数只有人员可以在给定时间完成的任务(同步修复了解关键部分的内容)。 –

+2

@NitinDandriyal你可能会想到其他语言。根据JVM规范,在另一个线程中可以看到具有与另一个线程的before-before关系的线程中的动作。并且在同一个监视器上进行同步创建了这种发生之前的关系。访问相同的易失性变量也可以。 –

回答

1

并非每个线程都必须执行同步作业(否则我们会失去使用线程的要点)。

高效的情形是,线程并独立工作(例如在一个线程中绘制图形元素同时播放背景音乐上的另一个)

2

是的,有在使用的同步性能损失。这里的并发性是保证共享变量读写的完整性。在你的情况下,如果没有同步,t1和t2可能会读取具有相同值的计数(称为1),所以当两个线程退出时,count的值为2,即使您应该预期它为3(因为它会增加两次)

1

如果速度不正确,则快速程序无效。

假设您的课程是处理您的帐户中的资金存款的课程。

假设您的三位客户要求银行向您的账户存入1000美元。假设银行不同步存款操作。

,因为它是不同步的,你可能有一个竞争条件:

  • 所有三个客户看了你的帐户的当前余额并行:0
  • 所有三个客户增加它:这样的账户余额变为$ 1000

结果:您的账户不是3000美元,而只有1000美元。但是,这比同步速度快了2毫秒。

您更喜欢这种情况吗?或者您希望操作额外增加2毫秒,但您的账户上有3000美元?

+2

我宁愿操作需要2个额外的毫秒并在我的账户中有3000美元。 –

+0

@JBNizet我不会介意别人在我的账户中转移6000美元而不是3000美元:) – CKing

0

要添加到@拔示巴的回答,在多个线程共享和访问这原子变量相同的资源的情况下,你需要确保只有一个线程访问在给定的时间资源。考虑修改上面下面的例子:

private int count = 0; 

synchronized void increment() { 
    count = count + 1; 
} 

如果使increment()方法​​,然后运行有不一致的状态的count变量的风险。具体而言,您的两个线程可能会交错(这意味着它们都在运行),而一个线程的增量操作可能会被另一个线程覆盖。

这里阅读更多有关同步:https://docs.oracle.com/javase/tutorial/essential/concurrency/interfere.html