1

そして、クラス A の任意のインスタンスをロックでき、それが何らかの方法でクラス A の別のインスタンスをロックするのに役立つという考えの罠に陥らないでください。これは古典的な初心者の間違いです。

私はそれを理解する前に数回間違いを犯しました。しかし、静的ロック オブジェクトは正しく機能します。

マイスレッド

package com.replanet;

public class MyThread extends Thread {

    private int x, y;
    private static Object lock3 = new Object();

    public MyThread(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public void run() {
        super.run();
        try {
            test_Method();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    private void test_Method() throws InterruptedException {
        synchronized (lock3) {
            System.out.println("test_Method " + Thread.currentThread().getName());
            for (int i = 0; i < Integer.MAX_VALUE; i++) {
                if (i == Integer.MAX_VALUE / 2) {
                    Thread.sleep(2000);
                    System.out
                            .println("Leaving test_Method on " + Thread.currentThread().getName());
                    return;
                }
            }
        }
    }

}

使用法

package com.replanet;

public class Main {

    public static void main(String[] args) {

        MyThread myThread1 = new MyThread(1, 2);
        MyThread myThread2 = new MyThread(1, 2);
        myThread1.start();
        myThread2.start();
    }
}

出力

test_Method Thread-0
Leaving test_Method on Thread-0
test_Method Thread-1
Leaving test_Method on Thread-1

非静的ロック オブジェクトでの出力 (私には合いません)

test_Method Thread-0
test_Method Thread-1
Leaving test_Method on Thread-1
Leaving test_Method on Thread-0

staticlock オブジェクトを使用するのは良い考えですか?

4

3 に答える 3

3

それ自体をロックすることができますClass- これはより理にかなっていて読みやすいです:

private void test_Method() throws InterruptedException {
        synchronized (MyThread.class) {
            System.out.println("test_Method " + Thread.currentThread().getName());
            for (int i = 0; i < Integer.MAX_VALUE; i++) {
                if (i == Integer.MAX_VALUE / 2) {
                    Thread.sleep(2000);
                    System.out
                            .println("Leaving test_Method in " + Thread.currentThread().getName());
                    return;
                }
            }
        }
    }

または、メソッドをインスタンス メソッドにする必要がない場合は、次のようにします。

private static synchronized void test_Method() throws InterruptedException {
            System.out.println("test_Method " + Thread.currentThread().getName());
            for (int i = 0; i < Integer.MAX_VALUE; i++) {
                if (i == Integer.MAX_VALUE / 2) {
                    Thread.sleep(2000);
                    System.out
                            .println("Leaving test_Method in " +  Thread.currentThread().getName());
                    return;
                }
            }
    }

new(ish) Lockクラスについても読みたいと思うかもしれません。

于 2013-02-19T09:40:51.850 に答える
1

静的ではなく、MyThread が 1 つのロック オブジェクトを共有する方がよいでしょう。よりオブジェクト指向。

于 2013-02-19T09:40:13.590 に答える
0

静的メンバーかインスタンス メンバーかは、必要なスコープによって異なりますが、プライベート オブジェクトをロックすることをお勧めます。これは、(明らかにパブリックな) クラス オブジェクトのロックに対する主な利点です。

于 2013-02-19T09:45:05.827 に答える