以下は、最も高速な技術が必要な、シーケンシャル (シングルスレッド) または同時 (マルチスレッド) のいずれかの方法で共通リソースにアクセスするかなり一般的なシナリオです。
より具体的には (以下のサンプル ソース コードを参照)、クラスは、共通のリソース (オブジェクト)を持つ(または) クラス ( )Manager
のいくつかのインスタンスを作成します。クラスは実際にはサブクラス化され、サブクラスの実装に応じて、同じスレッドまたは複数のスレッド (たとえば、 を介して) でハンドラを順次実行するために、そのメソッドがオーバーライドされます。Runnable
Callable
Handler
Store
Manager
execute()
ExecutorService
私の質問は、特にシングルスレッドアクセスの場合、同期が冗長であることを考慮して、各オブジェクトの(または) メソッドStore
内で共有オブジェクトへのアクセスを同期する最速の (オーバーヘッドの少ない) 方法は何でしょうか?マルチスレッドのサブクラスの実装もあるからです)。run
call()
Handler
Manager
たとえば、を呼び出す前後にからのオブジェクトsynchronized (this.store) {this.store.process()}
を使用するよりも、ブロックの方が優れているでしょうか? または、ストア アクセスごとに個別のメソッドを内部で使用すると、より高速になりますか? たとえば、 を呼び出す代わりに、次のように実行します。Lock
java.util.concurrent
this.store.process()
synchronized
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() {}
}