まず、なぜそこセキュリティスレッド
1.複数のスレッドが同じ共有している場合、グローバル変数や静的変数を書き込み操作を行う場合、データはそのスレッドの安全性の問題が発生している競合する可能性があります。しかし、競合が発生し、データを読んでいません。
第二に、コード例
1.コード
public class ThreadTrain implements Runnable {
private int trainCount = 100;
@Override
public void run() {
while (trainCount > 0) {
try {
Thread.sleep(500);
} catch (Exception e) {
}
sale();
}
}
public void sale() {
if (trainCount > 0) {
System.out.println(Thread.currentThread().getName() + ",出售第" + (100 - trainCount + 1) + "张票");
trainCount--;
}
}
public static void main(String[] args) {
ThreadTrain threadTrain = new ThreadTrain();
Thread t1 = new Thread(threadTrain, "①号");
Thread t2 = new Thread(threadTrain, "②号");
t1.start();
t2.start();
}
}
2.結果
3.分析します
一つの窓と窓の数2のチケットを販売しながら、いくつかのチケットは販売のために繰り返される、結論は複数のスレッドが同じグローバルメンバ変数を共有することがわかったときに、データの書き込み動作を行う競合が発生することがあります。
第三に、スレッドセーフなソリューション
1. 同期または複数のスレッド間で発生するロック(ロック)、データが競合する可能性があり(スレッドセーフ号)を使用して同期、スレッドは、現在の実行を行うことができます。コードの実装が完了した後ので、後の実行のために他のスレッドを聞かせていることを、ロックを解除します。このケースでは、不安スレッドの問題を解決することができます。
2.二つの方法でキーワード同期、達成するためにsynchronizedキーワードのロックを使用して構築されました:
2.1。改変は、同期メソッド呼び出しを有するように、ロックオブジェクトとして作用する、(すべての状態変数にアクセスする方法が同期されなければならない)メソッドを同期させる必要があります
2.2は直接同じで同期を必要とする方法を用いて修飾が、ロック粒度が微細であってもよく、ロックは、必ずしもこの目的ではないとして機能するブロックを同期して同期、他のオブジェクトがあってもよく、それは使用することがより柔軟です。
各Javaオブジェクトは、組み込みのロックとして知られている同期ロックを、達成するために使用することができます2.3、スレッドの前にロック自動的に同期ブロックに入る、通常の終了またはコードの完全なブロックを実行するコードのブロックは、例外解放され、出口がスローされますロックは、内蔵スレッドAの後に、あるミューテックス、のロックは、ロック、スレッドBを取得し、ブロックされたスレッドを解放するまでロック、同じロックを得るために、スレッドB。
3.コード(同期方法、他の方法を省略する)
public class ThreadTrain implements Runnable {
private int trainCount = 100;
@Override
public void run() {
while (trainCount > 0) {
try {
Thread.sleep(500);
} catch (Exception e) {
}
sale();
}
}
public synchronized void sale() {
if (trainCount > 0) {
System.out.println(Thread.currentThread().getName() + ",出售第" + (100 - trainCount + 1) + "张票");
trainCount--;
}
}
public static void main(String[] args) {
ThreadTrain threadTrain = new ThreadTrain();
Thread t1 = new Thread(threadTrain, "①号");
Thread t2 = new Thread(threadTrain, "②号");
t1.start();
t2.start();
}
}
3.1。結果(正常結果)
①号,出售第1张票
②号,出售第2张票
①号,出售第3张票
②号,出售第4张票
①号,出售第5张票
②号,出售第6张票
①号,出售第7张票
四、ThreadLocalの使い方
スレッドにアクセスするために、スレッドローカル変数を向上1.ThreadLocal自身のローカル変数(各スレッドが1つを有している)を有しています。
2. ThreadLocal変数のメンテナンスを使用する場合、ThreadLocalのが可変独立変数のコピーを使用して、スレッドごとに設けられ、各スレッドが独立コピーを対応する他のスレッドに影響を与えることなく、そのコピーを変更することができます。
3.コード
class Res {
// 生成序列号共享变量
public static Integer count = 0;
public static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>() {
protected Integer initialValue() {
return 0;
};
};
public Integer getNum() {
int count = threadLocal.get() + 1;
threadLocal.set(count);
return count;
}
}
public class ThreadLocaDemo2 extends Thread {
private Res res;
public ThreadLocaDemo2(Res res) {
this.res = res;
}
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + "---" + "i---" + i + "--num:" + res.getNum());
}
}
public static void main(String[] args) {
Res res = new Res();
ThreadLocaDemo2 threadLocaDemo1 = new ThreadLocaDemo2(res);
ThreadLocaDemo2 threadLocaDemo2 = new ThreadLocaDemo2(res);
ThreadLocaDemo2 threadLocaDemo3 = new ThreadLocaDemo2(res);
threadLocaDemo1.start();
threadLocaDemo2.start();
threadLocaDemo3.start();
}
}
4.結果
Thread-0---i---0--num:1
Thread-0---i---1--num:2
Thread-0---i---2--num:3
Thread-2---i---0--num:1
Thread-2---i---1--num:2
Thread-2---i---2--num:3
Thread-1---i---0--num:1
Thread-1---i---1--num:2
Thread-1---i---2--num:3
第五に、の終わり
1.今日、ここにこの停止!!!