omg,打了半天忘了存盘了,运行Java程序时一个crash死机了。。。
直接把今天看的部分放上来了
1. The synchronized Keyword
Before the Lock and Condition interfaces were added to JDK 5.0, the Java language used a different concurrency mechanism. Ever since version 1.0, every object in Java has an implicit lock. If a method is declared with the synchronized keyword, then the object's lock protects the entire method. That is, to call the method, a thread must acquire the object lock.
In other words,

public synchronized void method()
{
method body
}

is the equivalent of

public void method()
{
implicitLock.lock();
try
{
method body
}
finally { implicitLock.unlock(); }
}

For example, instead of using an explicit lock, we can simply declare the transfer method of the Bank class as synchronized.
The implicit object lock has a single associated condition. The wait method adds a thread to the wait set, and the notifyAll/notify methods unblock waiting threads. In other words, calling wait or notifyAll is the equivalent of

implicitCondition.await();
implicitCondition.signalAll();

However, the implicit locks and conditions have some limitations. Among them are:
You cannot interrupt a thread that is trying to acquire a lock.
You cannot specify a timeout when trying to acquire a lock.
Having a single condition per lock can be inefficient.
The virtual machine locking primitives do not map well to the most efficient locking mechanisms available in hardware.
What should you use in your codeLock and Condition objects or synchronized methods? Here is our recommendation:
1)It is best to use neither Lock/Condition nor the synchronized keyword. In many situations, you can use one of the mechanisms of the java.util.concurrent package that do all the locking for you. For example, on page 48, you will see how to use a blocking queue to synchronize threads that work on a common task.
2)If the synchronized keyword works for your situation, by all means, use it. You write less code and have less room for error. Example 1-5 shows the bank example, implemented with synchronized methods.
3)Use Lock/Condition if you specifically need the additional power that these constructs give you.
Note: At least for now, using the synchronized keyword has an added benefit. Tools that monitor the virtual machine can report on the implicit locks and conditions, which is helpful for debugging deadlock problems. It will take some time for these tools to be extended to the java.util.concurrent mechanisms.
2. Monitors
The locks and conditions are powerful tools for thread synchronization, but they are not very object oriented. For many years, researchers have looked for ways to make multithreading safe without forcing programmers to think about explicit locks. One of the most successful solutions is the monitor concept that was pioneered by Per Brinch Hansen and Tony Hoare in the 1970s. In the terminology of Java, a monitor has these properties:
~ A monitor is a class with only private fields.
~ Each object of that class has an associated lock.
~ All methods are locked by that lock. In other words, if a client calls obj.method(), then the lock for obj is automatically acquired at the beginning of the method call and relinquished when the method returns. Because all fields are private, this arrangement ensures that no thread can access the fields while another thread manipulates them.
~ The lock can have any number of associated conditions.
However, a Java object differs from a monitor in three ways:
~ Fields are not required to be private.
~ Methods are not required to be synchronized.
~ The lock has only one condition.
This disrespect for security enraged Per Brinch Hansen. In a scathing review of the multithreading primitives in Java, he wrote: "It is astounding to me that Java's insecure parallelism is taken seriously by the programming community, a quarter of a century after the invention of monitors and Concurrent Pascal. It has no merit." [Java's Insecure Parallelism, ACM SIGPLAN Notices 34:3845, April 1999]
3. Synchronized Blocks
Recall that each object has a lock. A thread can acquire the lock in one of two ways, by calling a synchronized method or by entering a synchronized block. If the thread calls obj.method(), it acquires the lock for obj. Similarly, if a thread enters a block of the form

synchronized (obj) // this is the syntax for a synchronized block
{
critical section
}
then the thread acquires the lock for obj. The lock is reentrant. If a thread has acquired the lock, it can acquire it again, incrementing the hold count. In particular, a synchronized method can call other synchronized methods with the same implicit parameter without having to wait for the lock.
It is legal to declare static methods as synchronized. If such a method is called, it acquires the lock of the associated class object. For example, if the Bank class has a static synchronized method, then the lock of the Bank.class object is locked when it is called.
4. Volatile 域
现在的处理器和编译器很有可能产生一些同步时的错误:
~ 多处理器的计算机会临时地在寄存器或缓存中存放数据,因此在不同处理器上运行的线程可能会从同一个内存区域获得不同的值。
~ 编译器为了提高效率,会重新排列指令顺序。但它们在操作时假设只有当有明确的更改指令时,内存数据才会改变。然而,实际上该数据有可能被另一线程修改。
如果你用锁保护由多线程访问的代码,就不会遇到这些问题。编译器在清洗缓冲区时会考虑到锁的存在,也不会错误地修改指令顺序。具体细节参见http://www.jcp.org/en/jsr/detail?id=133http://www-106.ibm.com/developerworks/java/library/j-jtp02244.html
Brian Goetz指出了应该何时使用同步:当你更改了某个下次可能会被其他线程访问的变量,或者访问了一个上一次可能被其他线程修改的变量,你就必须使用synchronization。
volatile关键字提供了一种同步实例域的访问的机制。如果把某一字段声明为volatile,编译器和虚拟机就会考虑到该数据域可能会同时被另一线程访问。
例如,boolean值的字段done可能被一个线程修改,并由另一个线程访问。有两种方法实现:
1)
public synchronized boolean isDone() {return done;}
private boolean done;
这种方法有一个潜在的缺陷:如果另一个方法锁住了对象,isDone方法可能会停滞。
2)
public boolean isDone() {return done;}
private volatile boolean done;
当然,访问一个volatile字段会比访问普通字段慢一些。
总结一下,对某字段的并发访问在以下情况中是安全的:
~ volatile字段
~ final字段,并且在构造器完成后就被修改。
~ 访问操作被锁保护
5. 锁死 Deadlocks
死锁的几种情况:(以银行转帐为例)
1)帐号1: $2,000 帐号2: $3,000
先试图从帐号1转3000到帐号2,再试图从帐号2转4000到帐号1。
容易得出,最后两个线程都会锁死。
2)有许多帐号,其中
帐号1: $1,990 其余帐号都是 $990
线程1: 从帐号1转$995到帐号2
其余线程: 从自己的帐号转出$995到其他帐号
显然,除了线程1,其余线程都被停滞。
线程1操作后,帐号1剩$995,帐号2剩$1,985,此时线程1使用signal方法随机恢复了一个线程,假设是线程3,但恢复后发现帐号3的资金仍不够转帐,于是继续停滞。
假设此时线程1又执行了从帐号1转出$997的指令,于是线程1也停滞。
系统锁死。
罪魁祸首就是signal方法。

posts - 403, comments - 310, trackbacks - 0, articles - 7
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

3.1 Java notes - Synchronization

Posted on 2007-04-22 20:25 ZelluX 阅读(357) 评论(0)  编辑  收藏 所属分类: OOP
2007-03-01 16:26:54
只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问