1. public class TestSeven extends Thread {
2. private static int x;
Copyright Tarena Corporation,2008.All rights reserved
3. public synchronized void doThings() {
4. int current = x;
5. current++;
6. x = current;
7. }
8. public void run() {
9. doThings();
10. }
1 1.}
Which is true?
A. Compilation fails.
B. An exception is thrown at runtime.
C. Synchronizing the run() method would make the class thread-safe.
D. The data in variable "x" are protected from concurrent access
problems.
E. Declaring the doThings() method as static would make the class
thread-safe.
F. Wrapping the statements within doThings() in a synchronized(new
Object()) { } block would make the class thread-safe.这是一个SCJP的题目,我想知道的是为什么把doThings声明为static的就可以使这个类变为线程安全的?

解决方案 »

  1.   

    加了后x和doThings()都请求TestSeven.class的锁,否则他们用的是不同的锁。
      

  2.   

    因为如果doThings()是非静态方法,同步用的是对象锁,如果是静态方法,同步是用的类锁。这个题中doThings()方法改变的是静态变量,如果用对象锁,调用不同对象的doThings()方法不会进行同步,而doThings()方法内的操作不是原子的,就会出现race condition。
      

  3.   

    看错了,应该是这样:同步static的值应该对TestSeven.class加锁
      

  4.   

    doThings()方法改变的是静态变量,如果用对象锁,调用不同对象的doThings()方法不会进行同步,而doThings()方法内的操作不是原子的,就会出现race condition。
      

  5.   

    我可不可以这样认为,如果这个方法是非静态的话,有没有synchronized就没有什么意义了?如果创建多个对象调用这个方法的话就都会对static的变量进行操作,就谈不上线程安全了。
      

  6.   

    因为是多个实例操作静态变量,在这种情况下非静态方法用synchronized可以说是没有什么意义的。
      

  7.   

    synchronized用来同步,保证某一时刻只有一个线程运行,但这是相对于一个对象而言的,就是说某对象中有多个线程时,synchronized来起到同步的作用,而你这个例子是有多个对象,每个对象都有自己的synchronized的方法,它们只能保证在自己对象内同步,不能使得不同对象之间的线程也同步,所以声明成static能解决这个问题,因为static是针对整个类的,整个类共用这一个,不存在每个对象拥有各自的方法