0

私はスレッドの安全性についてかなり読んでおり、オブジェクトの複数のインスタンスがスレッドの安全性に影響を与えるかどうかについて混乱しています。具体例を次に示します:
RGBColorというクラスがあり、赤、緑、青の値を設定してから色を返すとします。スレッドセーフティとJavaでのインスタンス

Public Class RGBColor { 
    private int red; 
    private int green; 
    private int blue; 
    Public RGBColor(int red, int green, int blue){ 
     this.red = red; 
     this.green = green; 
     this.blue = blue; 
    } 
    Public void setColor(int red, int green, int blue){ 
     this.red = red; 
     this.green = green; 
     this.blue = blue; 
    } 
    Public RGBColor getColor(){ 
     return this; 
    } 
} 

は今のプログラムは、例えば、そのクラスの複数のインスタンスを作成している場合:

RGBColor red = new RGBcolor(255,0,0); 
RGBColor blue = new RGBcolor(0,0,255); 

を今ここで質問です。これらのクラスのインスタンスは完全に独立していますか?スレッドの安全性が問題になるでしょうか?結局のところ私が理解しているように、RAMで異なる割り当てを持つ全く異なるオブジェクトでなければなりません。

もう1つの質問は、変数とメソッドが静的な場合です。

Public Class RGBColor { 
    private static int RED; 
    private static int GREEN; 
    private static int BLUE; 

    Public static void setColor(int red, int green, int blue){ 
     RED = red; 
     GREEN = green; 
     BLUE = blue; 
    } 
} 

スレッドの安全性に関しては、静的変数とメソッドはどのように処理されますか?

ps:2番目の例に欠陥があると更新されました。

+0

最初の質問への回答は「はい」です。オブジェクトのメソッドは「独立」です。オブジェクト上のメソッドを呼び出すと、そのオブジェクトにのみ影響します。質問2の答えは、通話を同期させる必要があるということです。あなたの例では、すべてのスレッドが同じ値を変更するので、おそらくそれは重要ではありません。 btw、静的メソッドでは 'this'を呼び出すことはできません。 –

+0

@JackFlamp大変ありがとうございました。また、投稿を更新しました。私は静的変数に 'this'を呼んでいることを完全に忘れてしまった。ありがとうございました:) –

答えて

1

オブジェクトにインスタンス変数がある最初のケースでは、オブジェクトは互いに独立して存在します。 1つを変更しても他のものには影響しません。

静的フィールドは、クラスに属し、いずれのオブジェクトにも属しません。コンストラクターはインスタンスを作成するためのものですか?静的変数を設定するためではなく、このケースのコンストラクタを持つことは混乱し、不要です。また、getColorでこれを使用しても動作しません。静的メソッドにはRGBColorのインスタンスがありません。

最初のケースでは、セッターを取り除き、インスタンス変数をfinalにするとオブジェクトは不変になり、複数のスレッドで安全に使用できます。

2番目のケースでは、複数のスレッドが互いの作業を上書きする可能性があり、変更を他のスレッドに見せることはできません。 (単にスレッドが値を変更しても、すぐに他のスレッドから見えることを意味するわけではありません)

このクラスのスコープに1組の値が本当に必要な場合は、不変オブジェクトを作成して静的なvolatile変数は、更新がアトミックで他のスレッドから見えるようにします。

1

これらのインスタンスは完全に独立していますか?私は スレッドの安全性が問題になると思いますか?

インスタンスはインスタンス間で独立しています。
複数のスレッドが1つのインスタンスに同時にアクセスし、それらのインスタンスのいずれかまたは両方がインスタンス状態に何らかの変更を加える場合があるため、スレッドの安全性に関する懸念があります。

例えば、RGBColorのインスタンスを作成し、複数のスレッドがこのインスタンスを操作できるとします。
ここでは、 setColor()の呼び出しが、他の呼び出しとインターリーブしてはならないという要件として質問します。
競合状態があり、これを処理する必要があります。それを処理する
は、あなたが例えば、各スレッドのメモリは常に更新されることを保証するために、フィールドvolatilesetColor()文を囲んで​​ステートメントを使用して作ることができる:

private volatile int red; 
private volatile int green; 
private volatile int blue; 
... 
public void setColor(int red, int green, int blue){ 
    synchronized (this){ 
    this.red = red; 
    this.green = green; 
    this.blue = blue; 
    } 
} 
はどのように静的変数であり、 がスレッドセーフになるとメソッドが処理されますか?

静的変数の場合は、インスタンス変数と同じ方法です。

たとえば、メソッドのスレッドセーフは、インスタンスのロックで実現できます。
静的メソッドの場合は、クラス自体のロックで実現する必要があります。

+0

答えをありがとう、実際にはここで別の質問を提起して、2つのスレッドが同じオブジェクトのインスタンスにアクセスしたかどうかをどのように知っていますか? –

+0

@Hosam Gemeiようこそ。同じオブジェクトに複数のスレッドがアクセスしているかどうかわからない場合は、Oracle Threadの章が良いスタート・ツールであると思います。https://docs.oracle.com/javase/tutorial/essential/concurrency/procthread.html – davidxxx

+0

ありがとう助けてくれてありがとう:) –

1

ここで「スレッドの安全性」について心配する必要はありません。あなたがもっと基本的なものを得ているからが間違っている。あるクラスの複数のインスタンスを持つことには意味がありません。対応するフィールドがすべて静的である場合です。

つまり、2番目の例では、redblue RGBColorオブジェクトを持つ意味がありません。インスタンス化するすべてのオブジェクトが互いに上書きされるためです。最後のものが勝ちます...

さらに、最初の例では、メソッドsetColor()は、スレッドの安全性の問題を引き起こす可能性があります。その方法は、一貫性のない状態(2つのスレッドがの同じオブジェクトで "同じ"時間に - しかし異なる引数を使って)でセッターを呼び出すことを可能にするためです。言い換えれば

:スレッドの安全性の問題をできるだけ早く:

  • が最初静的は程度であり、2番目のコード入力が
  • ので、著しく「悪い」である理由を悟ら何学んでいくつかの時間を費やします「共有」データは、複数のスレッドからアクセス可能です。そのため、その "共有"データに対する読み取り/書き込み操作は、常に完全に定義されていることを確認する必要があります。
+0

私は2番目の例では、 'static'メソッドが呼び出されたときに、' setColor'を 'synchronized'メソッドとして設定する必要があるかどうか分からないことが分かりました。その答えが必要であることをここから理解する。 ありがとうございます。 –

0

あなたの最初の質問に答えてください。 YES異なるオブジェクトはJVMで別々のハッシュコードを持ちます。しかし、あなたは(オブジェクトの変更がある場合)、オブジェクト上でスレッドの安全性を使用する必要があります同時に同じオブジェクトアクセスのトランザクションを考慮したときに

方法で

修飾子を同期を使用することができますスレッドの安全を確保する。同一のオブジェクトが異なるシステムによって同時にアクセスする場合に限ります。

あなたの2番目の質問に答えてください。 java内の静的または非静的オブジェクトは、そのオブジェクトの修飾子がに同期化された場合にのみスレッドセーフになります。それ以外にも、スレッドプールとカウントダウンを使用して、多数のスレッドを持つオブジェクトを効率的に処理できます。

関連する問題