2012-07-31 76 views
1

以下是访问公共资源的一种相当普遍的情况,无论是以顺序(单线程)还是并发(多线程)方式,需要最快的技术。最快的同步技术

更具体地(见下文样本源代码),一个Manager类创建一个Runnable(或Callable)类(Handler)具有共同的资源(Store对象)的一些实例中。取决于子类的实现,Manager类实际上是子类,并且它的​​方法被重写以在同一线程中或在多个线程中(例如,通过ExecutorService)顺序地运行处理程序。

我的问题是,这将是同步访问共享Store对象中的每个Handler对象的run(或call())方法中,尤其是考虑到最快(较少的开销)的方式,对于单个线程访问,那同步是多余的(但必须在那里,因为也有多线程Manager子类实现)。

会,例如,一个synchronized (this.store) {this.store.process()}块比,说还好,利用java.util.concurrent一个Lock对象,之前并调用this.store.process()后?或者单独的​​方法里面Handler每个商店访问速度会更快?例如,而不是调用this.store.process(),运行像

private synchronized void processStore() 
{ 
    this.store.process(); 
} 

以下是(样品)的源代码。

public class Manager 
{ 
    public Manager() 
    { 
     Store store = new Store(); // Resource to be shared 
     List<Handler> handlers = createHandlers(store, 10); 

     execute(handlers); 
    } 

    List<Handler> createHandlers(Store store, int count) 
    { 
     List<Handler> handlers = new ArrayList<Handler>(); 

     for (int i=0; i<count; i++) 
     { 
      handlers.add(new Handler(store)); 
     } 

     return handlers; 
    } 

    void execute(List<Handler> handlers) 
    { 
     // Run handlers, either sequentially or concurrently 
    } 
} 

public class Handler implements Runnable // or Callable 
{ 
    Store store; // Shared resource 

    public Handler(Store store) 
    { 
     this.store = store; 
    } 

    public void run() // Would be call(), if Callable 
    { 
     // ... 
     this.store.process(); // Synchronization needed 
     // ... 
     this.store.report(); // Synchronization needed 
     // ... 
     this.store.close(); // Synchronization needed 
     // ... 
    }  
} 

public class Store 
{ 
    void process() {} 
    void report() {} 
    void close() {} 
} 
+1

“process”,“report”,“close”可以并行执行吗?如果一个线程在其他线程仍然工作时调用“close”,会发生什么情况。这一切都是评估如何使用同步/锁定的基础。 Store中常见的数据结构是什么? 如果不清楚普通数据是什么,那么就不可能有一个普遍的答案。 – GandalfIX 2012-07-31 19:48:54

+0

问题涉及在商店对象或Handle对象(例如,processStore()方法)上进行同步,因此process(),report()和close()方法之间共享的任何数据,或者这些方法是否执行并行,应该被覆盖。 – PNS 2012-07-31 20:02:03

回答

3

一般来说:CAS同步<​​< Lock在速度方面。当然,这将取决于争用的程度和您的操作系统。我建议你尝试一下,确定哪一个是你需要的最快的。

Java还执行lock elision以避免锁定仅对一个线程可见的对象。

+3

...其中'<'的意思是“大于”:) – 2012-07-31 21:31:45

+0

是的,我还''为'比'更快! :-) – PNS 2012-07-31 22:43:05

+0

下面是synchronized()和Lock之间的一个简短而漂亮的比较:http://blog.rapleaf.com/dev/2011/06/16/java-performance-synchronized-vs-lock/ – PNS 2012-07-31 23:02:03

1

据我所知,如果你的应用程序运行或将以集群模式运行,那么同步将无法工作(不同的JVM),所以锁定将是唯一的选择。

如果公共资源是队列,那么你可以使用ArrayBlockingQueue,如果没有的话就开始对这个资源进行同步访问。