2010-12-15 50 views
1

我想验证以下我写的验证事实,即两个线程可以同时访问静态同步方法和非静态同步方法(因为锁在不同的对象上)。我得到了一个结果,但想知道我的解释是否正确实例和静态方法的并发测试的有效性

我跑了下面的代码,我看到变量我分别在静态和非静态方法打印时相同的值。这是对静态和非静态方法锁定两个不同对象并且两个线程可以同时访问它们这一事实的有效证明。

代码

import java.util.ArrayList; 
import java.util.List; 

public class TestStaticSynchronize { 

public static final TesteeClass obj = new TesteeClass(); 

/** 
* @param args 
*/ 
public static void main(String[] args) { 
    for(int i = 0; i < 50; i++) { 
     Runner run = new Runner(i); 
     Thread th = new Thread(run); 
     th.start(); 
    } 
} 

static class Runner implements Runnable { 

    private int i; 

    public Runner(int i) { 
     this.i = i; 
    } 

    public void run() { 
     if(i % 2 == 0) { 
      TesteeClass.staticSync(); 
     } else { 
      obj.instanceSync(); 
     } 
    } 

} 
} 

class TesteeClass { 

private static List<Integer> testList = new ArrayList<Integer>(); 


public static synchronized void staticSync() { 
    System.out.println("Reached static synchronized method " + testList.size()); 
    testList.add(1); 
} 

public synchronized void instanceSync() { 
    System.out.println("Reach instance synchronized method " + testList.size()); 
    testList.add(1); 
} 
} 

回答

1

你的评价是正确的。这是为什么。

所以,把你的同步实例方法,让我们把它改写在相当于synchronized块符号:

public void instanceSync() { 
    synchronized(this) { 
     System.out.println("..."); 
     testList.add(1); 
    } 
} 

当你写一个synchronized方法是同样的事情锁定对周围实例(即此)。使用静态方法,该参数不存在,那么静态的等效同步块是什么?它锁定在Class对象上。

public void classSync() { 
    synchronized(TestClass.class) { 
     System.out.println("..."); 
     testList.add(1); 
    } 
} 

所以这个实例是与表示TestClass类的对象不同的对象。这意味着有两个不同的锁正在使用,这会导致您发现的问题。最后你的测试程序是非常危险的,而不是线程安全的。实例方法,特别是在多线程情况下使用时,不应触及静态成员期间。将这些访问路由通过静态方法进行路由很好,但直接访问最糟糕的形式是严重错误。

有一种方式来编写你的程序的方式,它们都锁定在同一个对象上,但我认为重要的是你考虑为什么你要写这样的代码。是否因为你真的只想要很多地方共享这样的单一结构,但是无法获得对单个对象的引用?这是软件体系结构的核心,也是它在多线程应用程序中扮演的重要角色。我怀疑有比使用静态成员更好的选择,并且只使用一个所有位置都有引用的实例(希望不要使用单例模式,全局静态等)。

+0

谢谢。我了解使用这种静态成员的含义。但这似乎是验证行为的最佳方式。 – Fazal 2010-12-15 16:02:21

+0

够公平的。如果你只是试图证明这种行为,那么没关系。 :-) – chubbsondubs 2010-12-15 19:04:32

相关问题