synchronizedキーワード

4391 ワード

2つのスレッドを開いて、それぞれ2つの文字列を印刷し、文字列を1つの文字列で出力します。ロックをかけないと、半分の文字列が印刷されます。CPUは時間スライスを別のスレッドに割り当てて印刷し、半分の印刷が発生します。以下のテストです。
/**
 * synchronized   
 */
public class SyncTest {

    public static void main(String[] args) {
        SyncTest syncTest = new SyncTest();
        syncTest.init();
    }

    private void init() {
        final Outputer outputer = new Outputer();

        //      ,          
        new Thread(new Runnable() {
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    outputer.out1("meiran");
                }
            }
        }).start();

        new Thread(new Runnable() {
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    outputer.out2("zhoutong");
                }
            }
        }).start();
    }

    class Outputer {
        /**
         *         (            )
         *
         * @param name
         */
        public void out1(String name) {
            int length = name.length();
            synchronized (this) {
                for (int i = 0; i < length; i++) {
                    System.out.print(name.charAt(i));
                }
                System.out.println("");
            }
        }

        /**
         *      (           )
         *
         * @param name
         */
        public synchronized void out2(String name) {
            int length = name.length();
            for (int i = 0; i < length; i++) {
                System.out.print(name.charAt(i));
            }
            System.out.println("");
        }
    }
}
以上のコードで説明する必要がある問題:
1、対象にロックをかけ、thisキーを使うという意味は、この方法を呼び出す対象にロックをかけるということです。
2、方法の上でsynchronizedをプラスするのはthisキーワードを使うのと等価です。3、内部匿名クラスでローカル変数を使用し、ローカル変数はfinalである必要があります。
4、staticメソッドは非staticの内部クラスにアクセスし、非staticの内部クラスは外部クラスのメンバー変数にアクセスすることができますので、非staticの内部クラスのオブジェクトは外部クラスのオブジェクトから呼び出す必要があると説明します。
5、staticメソッドをstatic以外に調整するには、オブジェクトを作成する必要があります。
テスト用例2:
/**
 *   static        
 */
public class SyncTest2 {

    public static void main(String[] args) {
        SyncTest2 syncTest = new SyncTest2();
        syncTest.init();
    }

    private void init() {
        final Outputer outputer = new Outputer();

        //      ,          
        new Thread(new Runnable() {
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    outputer.out1("meiran");
                }
            }
        }).start();

        new Thread(new Runnable() {
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    outputer.out2("zhoutong");
                }
            }
        }).start();
    }

    static class Outputer {
        /**
         *          
         *
         * @param name
         */
        public void out1(String name) {
            int length = name.length();
            synchronized (Outputer.class) {
                for (int i = 0; i < length; i++) {
                    System.out.print(name.charAt(i));
                }
                System.out.println("");
            }
        }

        /**
         *                 
         *
         * @param name
         */
        public static synchronized void out2(String name) {
            int length = name.length();
            for (int i = 0; i < length; i++) {
                System.out.print(name.charAt(i));
            }
            System.out.println("");
        }
    }
}
以上のコードで説明する必要がある問題:
1、staticメソッドのロック対象はバイトコードファイルの対象です。
2、内部類はstaticの方法があってはいけません。静的な内部クラスとして定義しなければなりません。トップクラスに相当します。