スレッドセーフの問題を解決する
以前のブログスレッドセーフの問題
1.同期キーワード-モニターロックモニターロック
同期の最下層は、オペレーティングシステムのミューテックスロックを使用して実装されます。
- スレッドがロックを解放すると、JMMはスレッドに対応する作業メモリー内の共有変数をメインメモリーにフラッシュします。
- スレッドがロックを取得すると、JMMはスレッドに対応するローカルメモリを無効にします。その結果、モニターによって保護されるクリティカルセクションコードは、メインメモリから共有変数を読み取る必要があります。
1.メソッドの修飾子として-メソッドの定義の前
synchronized int add(int a,int b){
...}
synchronized static int add(int a,int b){
...}
2.同期コードブロックとして
synchronized(对象的引用){
......
}
3.コードのデモンストレーション
/**
* synchronized的语法使用示例
*/
public class ThreadDemo {
//同步方法
synchronized int add(int a,int b){
return 0;
}
synchronized static void sayHello(){
}
//同步代码块——能出现语句的地方
static void someMethod() {
Object object = new Object();
synchronized (object) {
}
}
}
2.同期を使用して、前のブログのコードのスレッドセーフの問題を解決します
public class ThreadDemo2 {
private static int n = 0;
private static final int COUNT = 100000;
static class Adder extends Thread{
@Override
public void run() {
for (int i = 0;i < COUNT;i++){
synchronized (Adder.class){
n++;
}
}
}
}
static class Suber extends Thread{
@Override
public void run() {
for (int i = 0;i < COUNT;i++){
synchronized (Adder.class){
//一定和上面的加同一把锁
n--;
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Adder();
Thread t2 = new Suber();
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(n);
}
}
3.揮発性キーワード
変更された共有変数は、可視性を保証し、順序を部分的に保証できます。
class ThreadDemo {
private volatile int n;
}