複数のスレッド間の同期
スレッドの安全性を理解します
同期の使用
デッドロック
Javaのメモリモデル
Vlolatileキーワード
ThreadLockキーワード
スレッドの安全性を理解します
スレッドセーフとは何ですか?
ときに複数のスレッドが同時に同じ共有するグローバル変数や静的変数を書き込み操作を行うと、データの競合が発生する可能性があり、スレッド安全性の問題です。
しかし、競合が発生し、データを読んでいません。
スレッドセーフなソリューション:
複数のスレッドまたはロック(ロック)の使用との間で同期同期。
原理:
同時に、一つのスレッドだけ現在のデータは操作を実行するようにします。ロックは、他のスレッドが操作を実行できるようにするために、現在のスレッドの実行が完了した後に解除された場合。私たちは不安スレッドの問題を解決することができるので、データの同時動作を回避するために、データの同期を実現します。
同期の使用:
二つの方法で同期:
最初:コードはおそらくそれらを含めるために、スレッドの安全性の問題を発生しますが、同期ブロックと呼ばれます。
コードは以下の通りであります:
同期(锁){
//質問かもしれない紛争にスレッドをブロック
}
第二:同期機能と呼ばれる同期の方法で変更、。
コードは以下の通りであります:
公共同期のボイドメソッド名(){
//質問かもしれない紛争にスレッドをブロック
}
方法論的に結合された場合は、静的なの静的な同期機能になり、静的なキーワード。
関数を使用して静的同期ロック機能バイトコードファイルオブジェクトに属し。
使用できるのgetClass()現在のクラス名で、取得する方法は、.classファイルに表すことができます。
同期方法及び同期コードブロックの違い:
同期機能デフォルトこの、またはこのクラスのクラス・ロックなどのオブジェクトを、
同期ブロックあなたは、ロックするものを選択することができ、全体のプロセスが行われるのではなく、コードスレッドの安全性の問題の一部のみを同期することができます。
ロック、ロックを保持しているスレッドが同期して行うことができるようにオブジェクト。
でも、CPUの実装を取得していないロックを保持しているスレッドで取得することはできません。
同期前提:
1、2つの以上のスレッド、または全く意味がなければなりません。
図2に示すように、同じロックを使用して複数のスレッド。
私たちは、運転中にその唯一のスレッド同期を確認する必要があります。
利点:マルチスレッドのセキュリティ問題を解決します。
短所:複数のスレッドがロックリソースをつかむ、ロック、資源の消費を決定する必要があります。
デッドロック
マルチスレッドのデッドロックとは何ですか?
同期ネスト同期は、プログラムを続行できません解放することができないロックで、その結果、ロック複数のスレッドがお互いを必要とする他の保持を実行します。
マルチスレッド三つの特徴
原子性:
すなわち、1つまたは複数の操作またはすべての操作を行うと、プロセスは、任意の因子の中断実行されず、またはそれを行いません。
可視性:
複数のスレッドが同じ変数にアクセスすると、スレッドは他のスレッドが直ちに変更された値を確認することができ、この変数の値を変更します。
注文:
プログラムの実行順序は、注文コードで実行しました。
Javaのメモリモデル
JavaのメモリモデルであるJavaメモリモデルは、JMMと呼ばれます。JMMはJava仮想マシン(JVM)は、コンピュータのメモリ(RAM)で動作を定義します。JVMは、コンピュータ全体の仮想モデルなので、JMMは、JVMの一部です。
Javaのメモリモデルは、複数のスレッドの可視性とどのように共有変数への同期を必要なときに間共有変数を定義します。
スレッド間通信
これは、スレッド間の情報交換にどの機構通信スレッドを指します。プログラミングコマンドで、二つのスレッド間の通信メカニズムは、メモリと、メッセージパッシングを共有しました。
共有メモリの同時実行モデルでは、一般的な状態は、書き込むことによって、スレッド間のスレッド間のプログラムを共有 - 暗黙通信、共有メモリ通信の典型的には、共通の目標状態を共有することによって通信するメモリを読み取ります。
共有メモリモデルは、Javaメモリモデル(と呼ばJMM)を指し、JMMは、共有変数に一つのスレッドを書くことを決めた、それは別のスレッド上で見ることができます。メインメモリ(主記憶装置)、各スレッドがプライベートローカルメモリ(ローカルメモリ)を有し、スレッド変数ストレージ間で共有:ビューの抽象的な点から、JMMはスレッドとメインメモリとの間の抽象関係を定義します、読み取り/書き込みにスレッドのコピーを保存されたローカル・メモリは、変数を共有しました。JMMローカルメモリは抽象的な概念であり、本物ではないです。これは、キャッシュ、書き込みバッファ、レジスタとその他のハードウェアおよびコンパイラの最適化をカバーしています。
しかし、共有変数は、メインメモリに格納され、各スレッドは、スレッドの安全性が発生するので、その複数のスレッドがアクセスしたときにデータがタイムリーに、メインメモリにローカルメモリをリフレッシュしていないかもしれませんが、独自のローカルメモリを持っています問題。
同時実行モデルのメッセージングにおいて、状態間には共通のスレッドが存在しない、明示的である典型的な実施形態では、スレッド間の明示的なメッセージを送信することによって通信しなければならないのJavaメッセージング待ち()と通知()があります。
揮発性
何である揮発性?
揮発性は、Javaによって提供同期している、それだけで唯一のマルチスレッドメモリの可視性を保証することができ、変数を変更することができ、軽量同期があり、複数のスレッドの正常実行を保証することはできません。最も徹底した同期は、同期として、秩序と可視性を確保します。
揮発性変数のいずれかの変更ではなく、ワーキングメモリのコピーのコピー、変更は速やかにメインメモリに書き込まれます。そのため、揮発性の変数への変更、および一度にすべてのスレッドを見ることができますが、volatile変数への変更が注文されることを保証することはできません。
揮発性と同期の違い:
単独の揮発性は、セキュリティスレッドを保証することはできません。(不可分)
①volatile軽量、変数のみを変更することができます。ヘビー級同期するだけでなく、修正方法。
②volatileは、複数のスレッドを同時にアクセス揮発性変数がブロックすることなく変更するので、データの可視性を、同期させるために使用することができない保証することができます。
synchronized不仅保证可见性,而且还保证原子性,因为,只有获得了锁的线程才能进入临界区,从而保证临界区中的所有语句都全部执行。多个线程争抢synchronized锁对象时,会出现阻塞。
线程安全性
线程安全性包括两个方面,①可见性。②原子性。
从上面可以看出:仅仅使用volatile并不能保证线程安全性。而synchronized则可实现线程的安全性。
ThreadLock
什么是ThreadLock?
ThreadLock提供了线程内存储变量的能力,是一个线程内部的存储类,可以在指定线程内存储数据,数据存储以后,只有指定线程可以得到存储数据。
当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
ThreadLocal的接口方法:
void set(Object value):设置当前线程的线程局部变量的值。
public Object get():该方法返回当前线程所对应的线程局部变量。
public void remove():将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。
需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。
protected Object initialValue():返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。
这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。
ThreadLocal特性:
ThreadLocal和Synchronized都是为了解决多线程中相同变量的访问冲突问题,不同的点是:
Synchronized是通过线程等待,牺牲时间来解决访问冲突;
ThreadLocal是通过每个线程单独一份存储空间,牺牲空间来解决冲突;
相比于Synchronized,ThreadLocal具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问到想要的值。
因此,当某些数据是以线程为作用域并且不同线程具有不同的数据副本的时候,就可以考虑采用ThreadLocal。