Mia*_*ach 11 java concurrency multithreading
我有一些关于Java多线程问题的问题.请尽可能多地为我提供帮助.
0)假设我们有2个银行账户,我们需要以线程安全的方式在它们之间转账.即
accountA.money += transferSum;
accountB.money -= transferSum;
Run Code Online (Sandbox Code Playgroud)
存在两个要求:
你能就此提出一些想法吗?
1)假设2个线程通过synchronized方法或使用显式锁来修改某个类字段.无论同步如何,都不能保证线程可以看到该字段,通过NOT synchronized方法读取它.- 这是对的吗?
2)通过notify方法唤醒的线程可以等待锁定多长时间?假设我们有这样的代码:
synchronized(lock) {
lock.notifyall();
//do some very-very long activity
lock.wait() //or the end of synchronized block
}
Run Code Online (Sandbox Code Playgroud)
我们可以说至少有一个线程会成功并抓住锁吗?由于某些超时,信号会丢失吗?
3)来自Java Concurrency Book的引文:
"单线程执行程序还提供了足够的内部同步,以保证任务所做的任何内存写入对后续任务都是可见的;这意味着对象可以安全地限制在"任务线程"中,即使该线程可能会被另一个时间替换掉时间."
这是否意味着,在单线程执行程序,执行剩下的代码的唯一线程安全的问题是数据的比赛,我们可以放弃volatile变量,而忽略所有的知名度的问题?它看起来像是解决大部分并发问题的通用方法.
4)所有标准的getter和setter都是原子的.如果字段标记为volatile,则无需同步它们.- 这是对的吗?
5)静态字段和静态块的启动由一个线程完成,因此不需要同步.- 这是对的吗?
6)为什么一个线程如果通过wait()方法离开锁定就需要通知其他人,但是如果它通过退出synchronized块而离开锁定则不需要这样做?
0:你不能.
确保原子更新很容易:您可以同步保存银行帐户的任何对象.但是你要么阻止所有读者(因为它们同步),要么你无法保证读者会看到什么.
但是,在诸如银行系统之类的大规模系统中,锁定频繁访问的对象是一个坏主意,因为它会引入等待系统.在更改两个值的特定情况下,这可能不是问题:它将发生得如此之快以至于大多数访问将是无竞争的.
当然有办法避免这种竞争条件.数据库为ba nk帐户做得非常好(尽管最终它们依赖于对事务结束的争用访问).
1)据我所知,除了由synchronized
或建立的保证之外,没有任何保证volatile
.如果一个线程进行同步访问而一个线程没有,则非同步访问没有内存屏障.(如果我错了,我相信我会得到纠正或至少被贬低)
2)引用JavaDoc:"唤醒的线程将无法继续,直到当前线程放弃对该对象的锁定." 如果您决定将睡眠放入同步块中,您将会感到不快.
3)我必须多次阅读该引用以确定,但我相信"单线程执行程序"是关键短语.如果执行程序仅运行单个线程,则该线程上的所有操作都存在严格的匹配前关系.这并不意味着在其他执行程序中运行的其他线程可以忽略同步.
4)否.long
并且double
不是原子的(参见JVM规范).AtomicXXX
如果要对成员变量进行不同步的访问,请使用对象.
5)不.我在JVM规范中找不到确切的引用,但2.17.5节暗示多个线程可以初始化类.
6)因为所有线程都等到一个线程进行通知.如果您处于同步块中,并且等待并且没有通知,则每个线程都将等待永远不会发生的通知.
归档时间: |
|
查看次数: |
632 次 |
最近记录: |