- 浏览: 111104 次
- 来自: ...
文章分类
最新评论
14.3.Synchronization.
Rule 1. synchronized:只影响多线程,不影响本线程 (Locks are owned per thread, so invoking a synchronized method from within another method synchronized on the same object will proceed without blocking, releasing the lock only when the outermost synchronized method returns.)
Rule 2. synchronized:只影响synchronized code,不影响非synchronized code. (Unsynchronized access does not wait for any locks but proceeds regardless of locks that may be held on the object.)
This is yet another reason to prefer accessor methods to public or protected fields: Using methods, you can synchronize access to the data, but you have no way to do so if the fields can be accessed directly outside your class.
Rule 3. synchronized: 只影响该类, 不影响子类或不受父类影响 (Synchronization requirements are a part of the implementation of a class.)
For example, a class that uses a private field as a lock object prevents an extended class from using the same synchronization mechanism. the extended class would have to define its own lock object (perhaps this) and override every method of the superclass to use this new synchronization mechanism.
Rule 4. synchronized: 类对象和实例对象互不影响(Acquiring the Class object lock in a static synchronized method has no effect on any objects of that class.) Rule 5. synchronized: 外围类实例和内嵌类实例互不影响(Another common use of the synchronized statement is for an inner object to synchronize on its enclosing object)
Like any other object, an inner object is independently synchronized. acquiring the lock of an inner object has no effect on its enclosing object's lock, nor does acquiring the lock of an enclosing object affect any enclosed inner objects. An inner class that needs to synchronize with its enclosing object must do so explicitly and a synchronized statement is a perfect toolthe alternative is to declare a synchronized method in the enclosing class just for the inner class to use.
Utility Method 1.
You can ask whether the current thread holds the lock on a given object by passing that object to the Thread class's static holdsLock method, which returns true if the current thread does hold the lock on that object. This is typically used to assert that a lock is held when needed. For example, a private method that expects to be invoked only from synchronized public methods might assert that fact:
assert Thread.holdsLock(this);
Conclusion 1. Don't Use synchronized(obj.getClass())
If you need a synchronized statement to use the same lock used by static synchronized methods, you can use the class literal for your class (see example below).It would also be wrong to use the Object method getClass to retrieve the Class object for the current instance: In an extended class, such as AttributedBody, that would return the Class object for AttributedBody not Body, and so again, different locks would be used and interference would not be prevented.
Conclusion 2. Client-side synchronization
An object can have its lock acquired, which prevents any of its synchronized methods from being invoked except by the lock holder performing the series of invocations. Similarly, you can acquire the locks of each of the objects involved and then invoke the series of methods on those objects but watch out for deadlock (see Section 14.7 on page 362). As long as the object's methods are already synchronized on the current object's lock, then other clients of the object need not use client-side synchronization.
14.4. wait, notifyAll, and notifyThe wait and notification methods are defined in class Object and are inherited by all classes. They apply to particular objects, just as locks do. There is a standard pattern that is important to use with wait and notification. The thread waiting for a condition should always do something like this: synchronized void doWhenCondition() { while (!condition) wait(); … Do what must be done when the condition is true … } A number of things are going on here:
Using notifyAll wakes up all waiting threads, whereas notify picks only one thread to wake up. Multiple threads may be waiting on the same object, possibly for different conditions. If they are waiting for different conditions, you should always use notifyAll to wake up all waiting threads instead of using notify. Otherwise, you may wake up a thread that is waiting for a different condition from the one you satisfied. That thread will discover that its condition has not been satisfied and go back to waiting, while some thread waiting on the condition you did satisfy will never get awakened. Using notify is an optimization that can be applied only when:
Otherwise you must use notifyAll. If a subclass violates either of the first two conditions, code in the superclass that uses notify may well be broken. To that end it is important that waiting and notification strategies, which include identifying the reference used (this or some other field), are documented for use by extended classes. In a multithreaded system you very rarely want to busy-wait. You should always suspend until told that what you are waiting for may have happened. This is the essence of thread communication with the wait and notifyAll/notify mechanism. |
14.5. Details of Waiting and Notification
You can invoke these methods only from within synchronized code, using the lock for the object on which they are invoked. The invocation can be directly made from the synchronized code, or can be made indirectly from a method invoked in such code. You will get an IllegalMonitorStateException if you attempt to invoke these methods on an object when you don't hold its lock. 细节 1. Only notifications that occur after the wait commences will affect a waiting thread. If no threads are waiting when either notifyAll or notify is invoked, the notification is not remembered. If a thread subsequently decides to wait, an earlier notification will have no effect on it. 细节 2. wait(long timeout)未必会导致 wait 在有限时间内返回 The use of a time-out is a defensive programming measure that allows you to recover when some condition should have been met but for some reason (probably a failure in another thread) has not. Because the lock of the object must be reacquired, the use of a time-out cannot guarantee that wait will return in a finite amount of time. 细节 3.wait始 终在循环中的另一个原因 It is also possible that some virtual machine implementations will allow so-called "spurious wakeups" to occurwhen a thread returns from wait without being the recipient of a notification, interruption, or time-out. This is another reason that wait should always be performed in a loop that tests the condition being waited on. |
14.7. Deadlocks
One common technique is to use resource ordering. With resource ordering you assign an order on all objects whose locks must be acquired and make sure that you always acquire locks in that order. This makes it impossible for two threads to hold one lock each and be trying to acquire the lock held by the otherthey must both request the locks in the same order, and so once one thread has the first lock, the second thread will block trying to acquire that lock, and then the first thread can safely acquire the second lock.
14.10. The Memory Model: Synchronization and volatile
Rule 1. 除long和double外, 变量的读写都是原子操作; 然而这对于 get / modify / set 操作序列 (像 a++, b--) 毫无帮助, 它们总是需要被同步
The language guarantees that reading or writing any variables, other than those of type long or double, is atomicthe variable will only ever hold a value that was written by some thread, never a partial value intermixing two different writes. This means, for example, that an atomic variable that is only written by one thread and read by many threads need not have access to it synchronized to prevent corruption because there is no possibility of interference. This does not help with getmodifyset sequences (such as ++), which always require synchronization
Rule 2. 原子存取并不意味着一个线程读出来的变量永远是最新的; 事实上, 如果没有同步, 一个线程可能永远都看不见另外一个线程对变量的更新
The rules that determine how memory accesses are ordered and when they are guaranteed to be visible are known as the memory model of the Java programming language. If all reads and writes to a variable occur only when a specific monitor is held, then each read of the variable is guaranteed by the memory model to return the value that was most recently written to it.
Rule 3. 作为第二种同步机制, 使用 volatile 声明的变量能够保证一个线程读出来的变量永远是最新的
There is a second synchronization mechanism that doesn't provide the exclusive access of monitors, but that again ensures that each read of a variable returns the most recently written valuethe use of volatile variables. Fields (but not array elements) can be declared with the volatile modifier. A write to a volatile variable synchronizes with all subsequent reads of that variable. If currentValue was declared as volatile then the example code we showed would be correctly synchronized and the latest value would always be displayed. The use of volatile variables is seldom a replacement for the use of synchronized methods or statements on its own, because they don't provide atomicity across different actions. Rather, volatile variables are most often used for simple flags to indicate something has occurred, or for writing lock-free algorithms that incorporate use of the atomic variables mentioned in Section 25.9.
Rule 4. volatile 另外一个副作用就是让long或double类型的变量读写也变成原子操作
几个最佳实践: A few other synchronization actions help make multithreading work nicely:
-
Starting a thread synchronizes with the first action performed by that thread when it executes. This ensures that a newly started thread sees any data that was initialized by the creating threadincluding the thread's own fields.
-
The final action of a thread synchronizes with any action that detects that the thread has terminatedsuch as calling isAlive or invoking join on that thread. This ensures, for example, that if you join a thread you can see all data written by that thread before it terminatedsuch as the results of its computation.
-
Interrupting a thread synchronizes with any other action that determines that the thread has been interrupted, such as the thread throwing InterruptedException or another thread invoking isInterrupted on the thread.
-
The write of the default value (zero, null, or false) to any field synchronizes with the first action in any thread. This ensures that even in incorrectly synchronized programs a thread will never see arbitrary values in fieldseither a specific value written by some thread will be seen or the default value of the field will be seen.
发表评论
-
The Object Primer
2004-12-11 11:21 5501,书名 被翻译成“ ... -
错误处理规范
2004-12-11 16:47 725错误处理规范 〇、概念澄清 概念 解释 错误 ... -
Java,误解为何如此之深
2005-08-24 13:50 559前几天被电话面试,问J ... -
Java:画蛇添足的编码规范
2005-09-02 13:13 540前几天公司培训编码规范: 第n条: ... -
交互设计: 股市帮凶
2008-05-04 21:30 609同事 Y 在线操作股票时, 把"买入"点成 ... -
交互设计: 火车上的厕所
2008-05-26 17:17 573有人在动车组的厕所前等了很久, 直到乘务员路过说厕所是被锁住了 ... -
设计原则与模式: 案例介绍--CppUnit
2008-06-01 20:15 571设计原则与模式: 案例介绍--CppUnit CppUnit ... -
工作流:形参,实参,相关数据
2004-12-11 11:40 625关于形参,实参,相关数据 一、形参(FormalParame ... -
工作流:第一次发版,过程总结
2004-12-11 11:42 667交流 即时讨论:小组成员咫尺之遥,有问题立即提出并解决 ... -
工作流:第一次发版,设计总结
2004-12-11 11:43 578整体 面向接口:消息系统,持久系统等,其实现都是可替换 ... -
Beyond Workflow : An Introduction to Vitria BusinessWare
2005-09-26 10:13 779一、简介 Busines ... -
Vitria BusinessWare: 存储与访问安全
2006-03-26 15:45 709事实上,BusinessWare使用LDAP做为存储机制和 ... -
Vitria BusinessWare: 平台与软件总线
2006-04-01 12:59 779经过一段时间的使用 ... -
Vitria BusinessWare: Web Services
2006-04-01 14:30 706BusinessWare的Web Services ... -
Web Services:自洽,编码,交换模型
2006-04-01 16:02 6161, 自洽 以前曾经写过: 目前WebServi ... -
Web Services:WSDL 1.1 规范中的几个错误
2006-04-01 16:40 680读完了WSDL 1.1的规范,令人惊讶的是发现似乎例子中有几个 ... -
C++/CLI:被忽视的集成技术
2006-05-17 20:02 715十几行代码,就使一个重要的旧系统组件,完全融入了基于.Ne ... -
AJP/JK:异构Web平台的集成技术
2006-05-25 21:44 666Tomcat Connector 可以将Tomcat ... -
Vitria BusinessWare: 事件与端口
2006-05-27 17:24 590Event BusinessWare是一个事件驱动的系统 ... -
WS-Security Interoperability Issues: WebSphere, JBoss, Axis and .Net
2006-08-31 22:46 796检验了一下WS-Security的互操作情况,涉及到 ...
相关推荐
Java中的synchronized:同步方法与线程安全
linux(Red_Hat)NTP时间同步的配置方法
与Objective-C指令类似,Synchronized获取一个互斥锁,运行一些代码,并在代码完成或引发异常时释放该锁。链接框架可通过获得同步。 要安装它,只需将以下行添加到您的Podfile中: pod "Synchronized", "~> 4.0"您...
时间触发网络讲义,涉及网络拓扑,调度,PCF帧,压缩函数,时钟校正等内容
volatile与synchronized的区别,锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility)
Synchronized与ThreadLocal
synchronized与单例的线程安全问题,博客地址:https://www.jianshu.com/p/486ed9c8662a
java语言 并发编程 ReentrantLock与synchronized区别 详解
java锁机制Synchronized java锁机制Synchronized java锁机制Synchronized java锁机制Synchronized
java中synchronized用法
你还在用synchronized?线程安全相关知识深入剖析
java synchronized的一些小实验,对帮助理解synchronized的使用有一定的帮助。
java里面synchronized用法
Synchronized关键字的用法
synchronized的几种示例研究,方法加锁,代码块加锁(this和对象)以及静态方法加锁的示例和效果。基本上包含了synchronized的几种常用的方式。
由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问...每个对象只有一个锁(lock)与之相关联。 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。
synchronized 测试案例,同步一个对象或者多个对象的案例均有,还有成功和失败案例的对比
java lock synchronized
This document specifies the third version of the Synchronized Multimedia Integration Language (SMIL, pronounced "smile"). SMIL 3.0 has the following design goals: ● Define an XML-based language...
CPU : Synchronized_instruction_advance