2016-11-29 4 views
0

私は、Dataインスタンスへの参照を共有する複数のスレッドを持つサーバーを持っているとします。クイック例えば、同期メソッドとReentrantLock

EDIT1:可読性

public void main() { 
Data data = new Data(); 
ReentrantLock rl = new ReentrantLock(true); 
ReadThread t1 = new ReadThread(data, rl); 
UploadThread t2 = new UploadThread(data, rl); 
t1.start(); t2.start(); 
} 

class ReadThread extends Thread { 
private Data data; 
private ReentrantLock lock; 

ReadThread(Data d, ReentrantLock l){ data = d; lock = l; } 

    void run(){ 
     lock.lock(); 
     try{ 
     data.put(aString) 
     } finally { lock.unlock(); } 
    } 
} 

class UploadThread extends Thread { 
private Data data; 
private ReentrantLock lock; 

UploadThread(Data d, ReentrantLock l){ data = d; lock = l; } 

    void run(){ 
     lock.lock(); 
     try{ 
     data.put(aString) 
     } finally { lock.unlock(); } 
    } 
} 

用に更新は、それが良い上記のようなロックを使用し、以下のようなputメソッドを同期させることです

class Data { 
private LinkedList<String> data = new LinkedList<String>(); 
synchronized void put(String x){ data.add(x); } 
} 

これはかなり荒れている、

私は、ほとんどの場合、並行性について懸念しています。

同期メソッドでは、クラス "データ"インスタンス/オブジェクトで同期が発生すると仮定して正しいですか?したがって、1つのUploadThreadがプッシュプロシージャ/メソッドを呼び出すことができ、1つのReadThreadが同じ手順を並行して実行できます。しかし、ReentrantLockの例を使用すると、一度に1つのスレッドだけがput呼び出しを実行できますか?

「データ」クラスでLinkedListを静的にして、putメソッドを同期させて静的にした場合はどうなりますか?どのアプローチが最適ですか?物事を静かにすると、私はmut exを失うのですか?

+5

「ロック」が間違っています。それを考えると、 'synchronized'を使います。またはもっと読む。はるかに。 –

+2

また、 'extends Thread'を使わないでください。 –

+1

また、コードを書式設定します。お願いします。これは判読不能に近いです。 –

答えて

2

Javaの場合​​セクションはリエントラントです。これは、1つのスレッドが必要な回数だけ同期セクションに入ることができるが、他のスレッドが存在しないときに新しいスレッドを入れることができることを意味する。これらのセクション内に現在あるスレッドはロックを取得し、すべての同期セクションを終了するとロックを戻します。メソッドのシグネチャで​​を宣言する以外にも、オブジェクトに対して直接​​を呼び出すことができます。例えば;

synchronized public void foo() { 

} 

public void foo() { 
    synchronized(this) { 

    } 
} 

ReentrantLockを一度にロックを取得することができる唯一のスレッドで​​と非常に類似している。これらの2つの方法は、同じ効果を有するであろう。スレッドがlock.lock()ステートメントに達すると、スレッドは別のスレッドによってロックが解除されるまで待機します。スレッドにすでにロックがある場合、スレッドは継続します。これは、1つの同期コードブロックでは不十分な、より複雑な状況で役に立ちます。

私はputメソッドを同期させて静的にした場合どうなりますか?

メソッドがstatic synchronizedの場合は、クラスのインスタンスではなくクラス自体がロックされていることを意味します。インスタンス​​のメソッドとは独立してロックされます。あなたのコードの場合


ここ一番簡単な方法は、スレッドセーフオブジェクトにDataオブジェクトを作成することです。このクラスのコードを編集できない場合は、オブジェクトをスレッドセーフラッパーにラップすることが有効な戦略です。

interface Foo { 
    void bar(); 
} 
class UnsafeFoo implements Foo { 
    @Override bar() { ... } 
} 
class ThreadSafeFoo implements Foo { 
    Foo foo; 
    ThreadSafeFoo(Foo foo) { this.foo = foo; } 
    @Override synchronized bar() { foo.bar(); } 
} 

Foo unsafe = new UnsafeFoo(); 
Foo safe = new ThreadSafeFoo(unsafe); 
+1

静的同期に関するあなたの答えをありがとう、私は何をしているので、私はクラスを編集することができますので、うまくいくはずです。感謝します :) – I2obiN

関連する問題