スレッドの安全性の問題
複数のスレッドが同じリソースを共有 (アクセス) する可能性があります
たとえば、同じオブジェクト、同じ変数、同じファイルにアクセスする場合
複数のスレッドが同じリソースにアクセスすると、スレッド セーフティの問題と呼ばれるデータの混乱やデータ セキュリティの問題が発生しやすくなります。
スレッド セーフティの問題はどのような状況で発生しますか。
複数のスレッドが、同じリソース
そして少なくとも 1 つのスレッドが書き込み操作を実行しています
例:
入金と出金の問題
入金と出金がそれぞれ 2 つのスレッドがあります
入金 出金
スレッド 1 残高 スレッド 2
1000 "----1000-----" 1000
1000 1000---- -》 2000
500 "-----1000-500
正解: 終了後の残高は 500 ではなく 1500 である必要があります
チケット購入の問題
2 スレッド
# スレッド 1 チケット番号 スレッド 2
1000 "---- 1000 -------" 1000
# 1000-1--- --》999
999 "-----1000-1
正解: 終了後の残高は 999 ではなく 998 である必要があります
チケット購入エラー (そうではありません)スレッド同期) 例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public class love implements Runnable{
private int piao=3000;
public boolean sale() {
if (piao<1) return false;
piao--;
String sk =Thread.currentThread().getName();
System.out.println(sk+ "卖了1张票,还剩下" +piao+ "张" );
return piao>1;
}
public void run() {
while (sale());
}
}
public class Main {
public static void main(String[] a) {
love tjlove = new love();
for (int i=1;i<=4;i++) {
Thread tj = new Thread(tjlove());
tj.setName( "" +i);
tj.start();
}
}
}
|
ログイン後にコピー
部分的な出力結果:

##スレッドの安全性の問題
分析の問題
スレッド A およびB 値 17
を持つクラス内の 1 つの変数に対して 1 つの操作を実行します。最終結果は 2 です。 18
ソリューション
ロック:
プロセス: まず、スレッドA が最初にこの 17 にアクセスします。読み込んだ後、ロックして 1 を入力します。動作は 18
に変更され、ロック期間中は他のスレッドから 17 にアクセスできません。
変更後、Enter を書き込み、次にロック解除 17
次に、スレッド B がそれにアクセスし、ロックし、上記の操作を繰り返して 19 になり、ロックを解除します。
これにより、同時に 1 つのスレッドだけがアクセスすることが保証されるため、セキュリティが保証されます。前のエラーこれらのスレッドが一緒にアクセスしていることが原因でした
スレッド同期
今述べたロック操作はスレッド同期テクノロジです
スレッド同期テクノロジを使用してスレッドの安全性の問題を解決できます
Java ではスレッド同期には 2 つの方法があります:
1. 同期ステートメント
2. 同期メソッド
同期ステートメント
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class love implements Runnable{
private int piao=3000;
public boolean sale() {
synchronized(this) {
if (piao<1) return false;
piao--;
String sk =Thread.currentThread().getName();
System.out.println(sk+ "卖了1张票,还剩下" +piao+ "张" );
return piao>0;
}
}
public void run() {
while (sale());
}
}
|
ログイン後にコピー
出力結果の一部:

synchronize(obj)の原則
1. 各オブジェクトには、関連する固有ロック (固有ロック) またはモニター ロック (モニター ロック) が関連付けられています。
2. 同期ステートメントを実行する最初のスレッドは、obj の内部ロックを取得できます。同期ステートメントのコードを実行した後、このロックを解放します
3. 1 つのスレッドが保持している限り、内部ロックが発生すると、他のスレッドは同時にこのロックを取得できなくなります。
✓ このロックを取得しようとすると、BLOCKED 状態になります。
4. 複数のスレッドがアクセスする場合同じ synchronized(obj) ステートメント
#obj は同期を実現するために同じオブジェクトである必要があります
同期メソッド
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class love implements Runnable{
private int piao=3000;
public synchronized boolean sale() {
if (piao<1) return false;
piao--;
String sk =Thread.currentThread().getName();
System.out.println(sk+ "卖了1张票,还剩下" +piao+ "张" );
return piao>0;
}
public void run() {
while (sale());
}
}
|
ログイン後にコピー
synchronized はコンストラクターを変更できません
本質同期メソッドの数
インスタンス メソッド: 同期 (この)
静的メソッド: 同期 (クラス オブジェクト)
同期ステートメントは同期メソッドよりも柔軟です
同期ステートメントは、ロックする必要があるコード範囲を正確に制御し、BLOCKED 状態のスレッドの数を減らし、労力を最大限に活用することができます。
スレッド同期を使用するテクノロジの後は、
スレッド セーフティの問題を解決すると、プログラムの実行効率が低下します。
ロックが追加されると、待機中のスレッドが存在し、より多くのロック操作とロック解除操作が発生するためです。
したがって、使用するのは本当に必要な場合のスレッド同期テクノロジー
以上がJava スレッドの安全性と同期の分析例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。